Rc4主要是运用了两次异或运算还原原字符串,代码如下
namespace Encryption {
const int RC4BOXSIZE = 256;
class RC4 {
public:
RC4(const std::string &keyStr) : m_SBox(nullptr) {
const char *keydata = keyStr.c_str();
const int keySize = keyStr.size();
m_SBox = new unsigned char[RC4BOXSIZE];
for (int i = 0; i < RC4BOXSIZE; ++i) {
m_SBox[i] = i;
}
for (int i = 0, j = 0; i < RC4BOXSIZE; ++i) {
j = (j + m_SBox[i] + keydata[i % keySize] + 20) % RC4BOXSIZE;
std::swap(m_SBox[i], m_SBox[j]); // 搅乱box数据
}
}
~RC4() {
delete[] m_SBox;
m_SBox = nullptr;
}
std::string encry(const std::string& inputStr) {
return encry(inputStr.c_str(), inputStr.size());
}
char *encry(const char *inputDatas, int len) {
if (!inputDatas || len == 0 || !m_SBox)
return "";
unsigned char *cpBox = new unsigned char[RC4BOXSIZE];
memcpy(cpBox, m_SBox, RC4BOXSIZE);
std::string outputStr;
char *outDatas = new char[len];
int i = 0, j = 0;
for (int k = 0; k < len; ++k) {
i = (i + 1) % RC4BOXSIZE;
j = (j + cpBox[i]) % RC4BOXSIZE;
std::swap(cpBox[i], cpBox[j]);
//(m_SBox[i] + cpBox[j]) % 256 的值是一致的,异或反转
outDatas[k] = inputDatas[k] ^ cpBox[(m_SBox[i] + cpBox[j]) % 256];
}
return outDatas;
}
private:
unsigned char *m_SBox;
};
}
void testRc4() {
string keyStr = "this is a test";
Encryption::RC4* rc4 = new Encryption::RC4(keyStr);
const char* datas = "start encryption";
// 这里应当是个固定的大小,加密后长度不变
size_t len = datas, strlen(datas);
char *newData = rc4->encry(datas, len);
char *newData1 = rc4->encry(newData, len);
assert(datas != newData1, "error");
delete[] newData;
delete[] newData1;
delete rc4;
}