1、由隨機數生成16位根密鑰k
2、通過+,-和位置移動,把16位密鑰k擴充爲256位的中間變量S和T
3、根據明文的長度Length,生成Length長度的密鑰流K
4、按Length,將密鑰流K和明文按字符異或。
具體代碼如下:
//參考huangyimo博客,《RC4加密算法的原理及實現》
#include <vector>
#include <iostream>
#include <fstream>
#include "time.h"
using namespace std;
/*
加密類
*/
class RC4 {
public:
/*
構造函數,參數爲密鑰長度
*/
RC4(int kl) :keylen(kl) {
srand((unsigned)time(NULL));
for (int i = 0; i < kl; ++i) { //隨機生產長度爲keylen字節的密鑰
int tmp = rand() % 256;
K.push_back(char(tmp));
}
}
/*
由明文產生密文
*/
void encryption(const string &, const string &, const string &);
private:
unsigned char S[256]; //狀態向量,共256字節
unsigned char T[256]; //臨時向量,共256字節
int keylen; //密鑰長度,keylen個字節,取值範圍爲1-256
vector<char> K; //可變長度密鑰
vector<char> k; //密鑰流
/*
初始化狀態向量S和臨時向量T,供keyStream方法調用
*/
void initial() {
for (int i = 0; i < 256; ++i) {
S[i] = i;
T[i] = K[i%keylen];
}
}
/*
初始排列狀態向量S,供keyStream方法調用
*/
void rangeS() {
int j = 0;
for (int i = 0; i < 256; ++i) {
j = (j + S[i] + T[i]) % 256;
//cout<<"j="<<j<<endl;
S[i] = S[i] + S[j];
S[j] = S[i] - S[j];
S[i] = S[i] - S[j];
}
}
/*
生成密鑰流
len:明文爲len個字節
*/
void keyStream(int len);
};
void RC4::keyStream(int len) {
initial();
rangeS();
int i = 0, j = 0, t;
while (len--) {
i = (i + 1) % 256;
j = (j + S[i]) % 256;
S[i] = S[i] + S[j];
S[j] = S[i] - S[j];
S[i] = S[i] - S[j];
t = (S[i] + S[j]) % 256;
k.push_back(S[t]);
}
}
void RC4::encryption(const string &plaintext, const string &ks, const string &ciphertext) {
ifstream in;
ofstream out, outks;
in.open(plaintext);
//獲取輸入流的長度
in.seekg(0, ios::end);
int lenFile = in.tellg();
if (lenFile == -1)
{
printf("please input file\n");
return;
}
in.seekg(0, ios::beg);
//生產密鑰流
keyStream(lenFile);
outks.open(ks);
for (int i = 0; i < lenFile; ++i) {
outks << (k[i]);
}
outks.close();
//明文內容讀入bits中
unsigned char *bits = new unsigned char[lenFile];
in.read((char *)bits, lenFile);
in.close();
out.open(ciphertext);
//將明文按字節依次與密鑰流異或後輸出到密文文件中
for (int i = 0; i < lenFile; ++i) {
out << (unsigned char)(bits[i] ^ k[i]);
}
out.close();
delete[]bits;
}
///////////////////////////////////////////////////////////
/*
解密類
*/
class RC4_decryption {
public:
/*
構造函數,參數爲密鑰流文件和密文文件
*/
RC4_decryption(const string ks, const string ct) :keystream(ks), ciphertext(ct) {}
/*
解密方法,參數爲解密文件名
*/
void decryption(const string &);
private:
string ciphertext, keystream;
};
void RC4_decryption::decryption(const string &res) {
ifstream inks, incp;
ofstream out;
inks.open(keystream);
incp.open(ciphertext);
//計算密文長度
inks.seekg(0, ios::end);
const int lenFile = inks.tellg();
inks.seekg(0, ios::beg);
//讀入密鑰流
unsigned char *bitKey = new unsigned char[lenFile];
inks.read((char *)bitKey, lenFile);
inks.close();
//讀入密文
unsigned char *bitCip = new unsigned char[lenFile];
incp.read((char *)bitCip, lenFile);
incp.close();
//解密後結果輸出到解密文件
out.open(res);
for (int i = 0; i < lenFile; ++i)
out << (unsigned char)(bitKey[i] ^ bitCip[i]);
out.close();
}
///////////////////////////////////////////////////////////
int main() {
RC4 rc4(16); //密鑰長16字節
rc4.encryption("明文.txt", "密鑰流.txt", "密文.txt");
RC4_decryption decrypt("密鑰流.txt", "密文.txt");
decrypt.decryption("解密文件.txt");
}
明文.txt爲預先準備好的文本變量。