📄 lmh_rc5.cpp
字号:
#include<iostream>
#include<string>
using namespace std;
//RC_5实现64位信息的加密解密过程
#define w 32 //字的bit数大小:基本单位为2个字块
#define R 12 // 一个内部RC5转换的轮数
#define b 16 //密钥字节长度:16个字节
#define T 2*(R+1)//扩展密钥表的字数
#define Pw 0xb7e15163
#define Qw 0x9e3779b9
#define N 8//明文消息的字节长度
typedef unsigned char byte;
class RC_5
{
private:
byte P[N];//名文消息以一个N字节数组形式存储共2w位
unsigned long A,B;//当前分组信息,初始时为明(密)文矩阵
byte C[N];//密文以一个字节数组形式存储共2w位
byte K[b];//一个 b个字节长的密钥序列
unsigned long S[2*R+2];//扩展密钥表的字数组
public:
void Encrypt();//加密操作
void decrypt();//解密操作
void Key_Expand ();//密钥扩展即计算S
void key_create();//创建一个密钥对象.
void ROTL(unsigned long &x,int n);//x = x<<<n:将x循环左移n位
void ROTR(unsigned long &x,int n);//x = x>>>n:将x循环右移n位
};
void RC_5::Encrypt()//加密操作
{
char str[100];
int i;
//输入需要加密的明文信息
scanf("%s",str);//str="请输入明文信息(字节为单位输入,用16进制形式:)";
for( i=0 ; i<8 ; i++)
scanf("%x" , &P[i] ) ;
//加载A和B的值:将明文信息分文两部分,将明文转化为32位int型整数
A = 0x0000 ;
B = 0x0000 ;
//第一个输入的字节作为A的低位字节。第四个输入的字节作为A的高位字字节,
//第五个输入字节作为B的低位字节,最后一个输入的字节作为B的高位字节。
//即采用little-endian
for ( i = 3 ; i >= 0 ; i -- )
{
A +=(unsigned long) P[i] ;
if( i ) A = A << 8 ;
B +=(unsigned long) P[i+4] ;
if( i ) B = B << 8 ;
}
key_create();//输入密钥
Key_Expand ();//密钥扩展过程
//重申轮函数
A = A + S[0];
B = B + S[1];
for (i = 1 ; i <= R ; i++)
{
A = A ^ B;
//将A循环左移B比特
ROTL(A,B%w);
A += S[2*i];
B =B ^ A;
ROTL(B,A%w);
B += S[(2*i)+1];
}
//得到密文:转换A和B为字节数
for(i=0; i<4; i++)
{
C[i] = ( A >> (8*i) ) & 0xff;
C[i+4] = ( B >> (8*i) ) & 0xff;
}
//输出明文
printf("明文:\n");
for(i=0; i<N; i++)
printf("%x ",P[i]);
printf("\n");
//输出密文
printf("加密后所得到的密文是:\n");
for(i=0; i<N; i++)
printf("%x ",C[i]);
printf("\n");
printf("\n");
}
void RC_5::decrypt()//解密操作
{
char str[100];
int i;
//输入需要解密的密文信息
scanf("%s", str);//str="请输入密文信息(字节为单位输入,用16进制形式:)"
for( i = 0 ; i < 8 ; i ++)
scanf("%x" , &C[i] ) ;
//将密文信息分文两部分,将密文转化为32位int型整数,little_endian
A = 0 ;
B = 0 ;
for ( i = 3 ; i >= 0 ; i -- )
{
A += C[i] ;
if( i ) A <<= 8 ;
B += C[i+4];
if( i ) B <<= 8 ;
}
key_create();//输入密钥
Key_Expand ();//密钥扩展过程
//重申轮函数
for (i = R ; i >=1 ; i--)
{
B -= S[(2*i)+1];
ROTR(B,A%w);
B =B ^ A;
A -= S[(2*i)];
ROTR(A,B%w);
A =A ^ B;
}
B -= S[1];
A -= S[0];
//得到明文:转换A和B为字节数
for(i=0; i<4; i++)
{
P[i] = ( A >> (8*i) ) & 0xff;
P[i+4] = ( B >> (8*i) ) & 0xff;
}
//输出密文
printf("密文:\n");
for(i=0; i<N; i++)
printf("%x ",C[i]);
printf("\n");
//输出明文
printf("密文解密后所得到的明文是:\n");
for(i=0; i<N; i++)
printf("%x ",P[i]);
printf("\n");
printf("\n");
}
void RC_5::ROTL(unsigned long &x,int n)//x = x<<<n:将x循环左移n位(0=<n<32)
{
int i;
unsigned long temp;
int rotl[32];//存放移出的比特
for(i=0; i<n; i++) //x左移并保存移出的比特
{
//取最高位
if(x&0x80000000) rotl[i] = 1;
else rotl[i] = 0;
x = x<<1;
}
temp = 0x0000;
//计算移出的比特的值
for(i=0; i<n; i++)
{
temp += rotl[i];
if(i<n-1) temp = temp<<1;
}
x += temp;
}
void RC_5::ROTR(unsigned long &x,int n)//x = x<<<n:将x循环右移n位
{
if(n)
{
unsigned long temp;
temp = x <<(w-n);
x = temp + (x>>n);
}
}
void RC_5::key_create()//输入密钥
{
int i ;
string str ;
cin >> str ;//str="请输入密钥(以字节为单位输入,用16进制形式)"
//输入密钥
for( i= 0 ; i < b ; i ++ )
scanf("%x" , &K[i] ) ;
}
void RC_5::Key_Expand ()//密钥扩展
{
int i, j, ll;
//初始化扩展密钥表
S[0] = Pw ;
for( i = 1 ; i < T ; i++) //t = 2*r+2
S[i] = S[i-1] + Qw;
//把b字节长的密钥K[0, …,b-1]转换成c-字阵列L[0, …,c-1]
unsigned long L[4];//c=b*8/w=4;
ll = 4;
for( i = 0 ;i < 4 ; i++ )
{
L[i] = 0 ;
for( j = 3 ;j >= 0 ; j--)
{
L[i] += K[ i*4+j ] ;
if(j) L[i] <<= 8;
}
}
//为了增强复杂性,可对阵列S,L做多次处理:
int x , y , k ;
i = j = x = y = 0;
if(ll<T) k = 3 * T ;
else k = 3 * ll;
while( k-- )
{
S[i] = ( S[i] + x + y ) << 3;
x = S[i] ;
i = (i+1) % T ;
L[j] = ( L[j] + x + y ) << (x+y) ;
y = L[j] ;
j = ( j + 1 ) % ll ;
}
}
void main()
{
freopen("in_lmhrc5.txt" , "r" , stdin);
freopen("out_lmhrc5.txt" , "w" , stdout);
RC_5 lmhrc5;
bool f;
string str;
cin>>str;//str="加密还是解密?1加密,0解密";
cin>>f;
if(f)lmhrc5.Encrypt();
else lmhrc5.decrypt();
cin>>str;
cin>>f;
if(f)lmhrc5.Encrypt();
else lmhrc5.decrypt();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -