/*程序用到的头文件*/
#include<math.h>
#include<fstream.h>
#include<iostream.h>
//此程序为RC5加密算法的实现--参数32/16/16
const int w=32; //定义字长为32比特
const int r=16; //定义循环轮数为16
const int b=16; //定义密钥长度为16个字节
const int t=34; //定义子密钥的个数为34个,即2*16+2
const int c=4; //定义存放以字为单位长度的数组的元素个数为4,即16*8/32=4
const long P=0xB7E15163; //定义一个常量P,用来扩展子密钥
const long Q=0x9E3779B9; //定义一个常量Q,用来扩展子密钥
typedef unsigned char BYTE; //定义BYTE为char类型,即长度为一个字节,也是数组K中元素的类型
typedef unsigned int DWORD; //定义DWORD为int类型,即长度为四个字节,也是数组L和S中元素的类型
struct DDWORD
{
DWORD left;
DWORD right;
};
static DWORD S[t]; //定义一个存放子密钥的数组S
static BYTE K[b]; //定义一个存放密钥的数组K
static DWORD L[c]; //定义一个以字为单位的数组L
#define ROTL(x,y) ((x)<<(y&(w-1)))|((x)>>(w-(y&(w-1)))) //将x循环左移y位
#define ROTR(x,y) ((x)>>(y&(w-1)))|((x)<<(w-(y&(w-1)))) //将x循环右移y位
void InitialKey() //初始化子密钥数组s
{
S[0]=P;
for(int i=1;i<t;i++)
{
S[i]=S[i-1]+Q;
}
}
void Transfer(BYTE*K) //把以字节为单位的数组赋给以双字长为单位的数组
{
int m;
for(int i=0;i<c;i++) //初始化数组L
{
L[i]=0;
}
for(int j=0;j<b;j++) //把以字节为单位的密钥数组K赋给以字为单位的数组L
{
m=(K[j]&0xff)<<(8*(j%4)); //每4个字节为一轮,依次左移0位,8位,16位,24位
L[j/4]=L[j/4]+m; //4个字节左移后相加即得到数组L中的一个元素
}
}
void MixSL() //将数组S和L混合以得到子密钥数组S
{
int i=0,j=0;
int A=0,B=0;
for(int k=0;k<(3*t-1);k++)
{
A=S[i]=ROTL(S[i]+A+B,3); //将(S[i]+A+B)循环左移3位
B=L[j]=ROTL(L[j]+A+B,(A+B)); //将(L[j]+A+B)循环左移(A+B)位
i=(i+1)%(t); //将(i+1)/t的余数赋给i
j=(j+1)%(c); //将(j+1)/c的余数赋给j
}
}
void Encryption(DDWORD source,DDWORD dest,DWORD *S) //双字加密函数
{
DWORD A=source.left; //初始化A为明文中前一个双字长的内容,即明文分组的左半部分
DWORD B=source.right; //初始化B为明文中后一个双字长的内容,即明文分组的右半部分
A=A+S[0];
B=B+S[1];
for(int i=1;i<=r;i++) //r轮循环
{
A=ROTL(A^B,B)+S[2*i];
B=ROTL(B^A,A)+S[2*i+1];
}
dest.left=A; //把变换后的A赋给密文分组的左半部分
dest.right=B; //把变换后的B赋给密文分组的后半部分
}
void Decryption(DDWORD source,DDWORD dest,DWORD *S)//双字解密函数
{
DWORD A=source.left; //初始化A为密文中前一个双字长的内容,即密文分组的左半部分
DWORD B=source.right; //初始化B为密文中后一个双字长的内容,即密文分组的右半部分
for(int i=1;i<=r;i++) //r轮循环
{
B=ROTR((B-S[2*i+1]),A)^A;
A=ROTR((A-S[2*i]),B)^B;
}
B=B-S[1];
A=A-S[0];
dest.left=A; //恢复明文的左半部分
dest.right=B; //恢复明文的右半部分
}
void Crypt(char *sourcefile,char *destfile)
{
ifstream fin; //定义一个读文件
ofstream fout; //定义一个写文件
fin.open(sourcefile,ios::binary);
fout.open(destfile,ios::binary);
DDWORD sour,dest;
fin.seekg(ios::beg);
while(!fin.eof())
{
fin.read((char *)(&sour),sizeof(sour));
Encryption(sour,dest,S);
fout.write((char*)(&dest),sizeof(dest));
}
fin.close ();
fin.close ();
}
void Decrypt(char *sourcefile,char *destfile)
{
ifstream fin; //定义一个读文件
ofstream fout; //定义一个写文件
fin.open(sourcefile,ios::binary);
fout.open(destfile,ios::binary);
fin.seekg(ios::beg);
DDWORD sour,dest;
while(!fin.eof())
{
fin.read((char *)(&sour),sizeof(sour));
Decryption(sour,dest,S);
fout.write((char*)(&dest),sizeof(dest));
}
fin.close();
fout.close();
}
void main()
{
InitialKey();
BYTE key[b];
cout<<"请输入密钥(1~16个):";
cin.getline(key,16);
Transfer(key);
MixSL();
char Plain[30],Crypto[30],Reco[30];
cout<<"请输入你所要加密的文件名:";
cin.getline(Plain,30);
cout<<"请输入加密后的文件名:";
cin.getline(Crypto,30);
Crypt(Plain,Crypto);
cout<<"请输入解密后的文件名:";
cin.getline(Reco,30);
Decrypt(Crypto,Reco);
}