📄 des_2005p.cpp
字号:
typedef unsigned char word8;
typedef unsigned short word16;
typedef unsigned long word32;
#include <iostream.h>
#include <iomanip.h>
// 字节取位数组
word8 B1bit[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
// 密钥编排函数KS,由8字节的密钥key,生成16个48位的子密钥keyi
// 密钥各位的编号,从第一字节高位开始。明文的位编号也如此。
void KS(word8 *key,word8 (*keyi)[48])
{ word8 i,j,k,l,m,temp,pc1key[56];
// 密钥置换选择1(PC_1:56位-->56位)数组
word8 pc1[56]={
56,48,40,32,24,16, 8,
0,57,49,41,33,25,17,
9, 1,58,50,42,34,26,
18,10, 2,59,51,43,35, // C0
62,54,46,38,30,22,14,
6,61,53,45,37,29,21,
13, 5,60,52,44,36,28,
20,12, 4,27,19,11,3 }; // D0
// 密钥位移数组
word8 movkey[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
// 密钥置换选择2(PC_2:56位-->48位)数组
word8 pc2[48]={
13,16,10,23, 0, 4, 2,27,
14, 5,20, 9,22,18,11,3,
25, 7,15, 6,26,19,12,1,
40,51,30,36,46,54,29,39,
50,44,32,47,43,48,38,55,
33,52,45,41,49,35,28,31};
for (i=0;i<56;i++) // 进行置换选择PC_1
{ //密钥的56个有效位经PC_1变位后存于数组pc1key中
l=pc1[i];
k=l>>3;
m=l&07;
pc1key[i]=(key[k]&B1bit[m])?1:0;
} // pc1key的前28元素是C,后28个是D
for (i=0;i<16;i++)
{
for (j=0;j<movkey[i];j++) // 循环左移(往前(高位)移)C、D
{ for (temp=pc1key[0],k=0;k<27;k++) pc1key[k]=pc1key[k+1];
pc1key[k]=temp;
for (temp=pc1key[28],k=28;k<55;k++) pc1key[k]=pc1key[k+1];
pc1key[k]=temp;
}
for (j=0;j<48;j++) // 进行置换选择PC_2
keyi[i][j]=pc1key[pc2[j]];
}
}
void bit_to_byte(word8 *bt,word8 *bb,word16 n)
{ // 将位bt(8*n位)-->n个字节bb;每个字节中,在前的是高位
word16 j,m,k;
word8 temp;
for (j=m=0;j<n;j++)
{ for (temp=0,k=0;k<8;k++)
{ m=j*8+k;
temp=(temp<<1)|bt[m];
}
bb[j]=temp;
}
}
// 密码函数f(R,Ki)
void frk(word8 *r,word8 *ki,word8 *pr)
{ // r,ki,pr中每个元素为1个二进制位
word8 i,j,k,m,n,x[8],p0[32],Er[48];
// 比特扩展变换(E:32位-->48位)数组
word8 E[48]={
31, 0, 1, 2, 3, 4, 3, 4,
5, 6, 7, 8, 7, 8, 9,10,
11,12,11,12,13,14,15,16,
15,16,17,18,19,20,19,20,
21,22,23,24,23,24,25,26,
27,28,27,28,29,30,31,0};
// 8个S盒:S1-S8
word8 S[8][4][16]={
14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13, /* S1 */
15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9, /* S2 */
10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12, /* S3 */
7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14, /* S4 */
2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3, /* S5 */
12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13, /* S6 */
4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12, /* S7 */
13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11}; /* S8 */
// 密码置换(P:32位-->32位)数组
word8 P[32]={
15, 6,19,20,28,11,27,16,
0,14,22,25, 4,17,30,9,
1, 7,23,13,31,26, 2,8,
18,12,29, 5,21,10, 3,24};
for (i=0;i<48;i++) Er[i]=r[E[i]]; // 32位扩展成48位
for (i=0;i<48;i++) Er[i]=Er[i]^ki[i]; // 异或
for (i=k=0;k<8;k++,i+=6)
{ // 8个S盒变换,每个x[i]中保存4位
m = (Er[i] << 1)|Er[i+5];
n = (Er[i+1]<<3)|(Er[i+2]<<2)|(Er[i+3]<<1)|Er[i+4];
x[k] = S[k][m][n];
}
for (i=j=0;i<8;i++)
for (k=4;k<8;k++)
{
p0[j]=(x[i]&B1bit[k])?1:0;
j++;
}
for (i=0;i<32;i++) pr[i]=p0[P[i]];
}
// 明文初始置换函数IP
// x为8字节明文,x0为明文经M1置换后的64位
// 明文中的位从第一个字节开始编号,高位在前
void IP(word8 *x,word8 *x0)
{ // 明文初始变位(M1:64位-->64位)数组
word8 M1[64]={
57,49,41,33,25,17, 9,1,
59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,
63,55,47,39,31,23,15,7,
56,48,40,32,24,16, 8,0,
58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6};
word8 i,j,k,m;
for (k=i=0;i<64;i++)
{ // 8字节明文分解为64位并进行初始变位
j = M1[i];
k = j >> 3;
m = j & 07;
x0[i] = (x[k] & B1bit[m]) ? 1:0;
}
}
//DES加密/解密函数
void DES(word8 *x,word8 *key,word8 *c,word8 mod)
{ // 8字节明文x-->8字节密文c;mod=0:加密 mod=1:解密
word8 x0[64],c0[64],keyi[16][48],pr[32],*Li,*Ri,*t;
word8 i,j,Rnd;
// 明文初始变位的逆变位(M2:64位-->64位)数组
word8 M2[64]={
39,7,47,15,55,23,63,31,
38,6,46,14,54,22,62,30,
37,5,45,13,53,21,61,29,
36,4,44,12,52,20,60,28,
35,3,43,11,51,19,59,27,
34,2,42,10,50,18,58,26,
33,1,41, 9,49,17,57,25,
32,0,40, 8,48,16,56,24};
KS(key,keyi); //生成的16个子密钥存于二维数组keyi中
IP(x,x0); //明文x经初始变位后,结果存于x0中
Li=x0;Ri=x0+32;//Ri指向x0的右边32位
for (Rnd=0;Rnd<16;Rnd++)
{ //进行16轮加密/解密
if (mod==0)j=Rnd;
else j=15-Rnd;
frk(Ri,keyi[j],pr);
for (i=0;i<32;i++) Li[i]=pr[i]^Li[i]; //异或
t=Li;
Li=Ri;
Ri=t;
}
for (i=0;i<32;i++) c0[i]=Ri[i];
for (j=0;j<32;j++,i++) c0[i]=Li[j];
for (i=0;i<64;i++) x0[i]=c0[M2[i]]; /* M2(R16L16) */
bit_to_byte(x0,c,8); //8个字节加密/解密结果存于c中
}
void main()
{
word8 x[9]="Goodbye!"; //明文
word8 key[8]={0x5b,0x5a,0x57,0x67,0x6a,0x56,0x67,0x6e};//密钥
word8 i,c[8],x1[8];
cout<<"明文:";
for (i=0;i<8;i++) cout<<x[i]<<" ";
cout<<"\n密钥:";
for (i=0;i<8;i++)
cout<<setfill('0')<<hex<<(int)key[i]<<" ";
DES(x,key,c,0); //加密
cout<<"\n密文:";
for (i=0;i<8;i++)
cout<<setfill('0')<<hex<<setw(2)<<(int)c[i]<<" ";
cout<<"\t(ASCII值)\n密文:";
for (i=0;i<8;i++)
cout<<setfill(' ')<<setw(2)<<c[i]<<' ';
DES(c,key,x1,1); //解密
cout<<"(字符)\n解密得到的明文:\n ";
for (i=0;i<8;i++) cout<<x1[i]<<" ";
cout<<"\n\n";
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -