📄 des.cpp
字号:
// DES.cpp : DES算法试验
//算法注视:实现中的1个byte表示算法中的一位
//
#include "stdafx.h"
//IP、IP_1矩阵
char IP_Matrix[][8]={
{58,50,42,34,26,18,10,2},
{60,52,44,36,28,20,12,4},
{62,54,46,38,30,22,14,6},
{64,56,48,40,32,24,16,8},
{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}
};
char IP_1_Matrix[][8]={
{40,8,48,16,56,24,64,32},
{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}
};
//E矩阵
char E_Matrix[][6] = {
{32, 1, 2, 3, 4, 5},
{4, 5, 6, 7, 8, 9},
{8, 9, 10, 11, 12, 13},
{12, 13, 14, 15, 16, 17},
{16, 17, 18, 19, 20, 21},
{20, 21, 22, 23, 24, 25},
{24, 25, 26, 27, 28, 29},
{28, 29, 30, 31, 32, 1}
};
//S盒子
char S_Box[8][64] = {
/* S1 */
{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},
/* S2 */
{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},
/* S3 */
{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},
/* S4 */
{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},
/* S5 */
{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},
/* S6 */
{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},
/* S7 */
{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},
/* S8 */
{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}
};
//密码PC1矩阵
char PC1_Matrix[][7] = {
{57, 49, 41, 33, 25, 17, 9},
{ 1, 58, 50, 42, 34, 26, 18},
{10, 2, 59, 51, 43, 35, 27},
{19, 11, 3, 60, 52, 44, 36},
{63, 55, 47, 39, 31, 23, 15},
{ 7, 62, 54, 46, 38, 30, 22},
{14, 6, 61, 53, 45, 37, 29},
{21, 13, 5, 28, 20, 12, 4}
};
//密码PC2矩阵
char PC2_Matrix[][6] = {
{14, 17, 11, 24, 1, 5},
{3, 28, 15, 6, 21, 10},
{23, 19, 12, 4, 26, 8},
{16, 7, 27, 20, 13, 2},
{41, 52, 31, 37, 47, 55},
{30, 40, 51, 45, 33, 48},
{44, 49, 39, 56, 34, 53},
{46, 42, 50, 36, 29, 32}
};
//密码LS(循环左移)
char LS_Matrix[]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
//P矩阵
char P_Matrix[] = {
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
//循环左移算法
void LS(int i,char *pkey)
{
char temp[28];
for(int j=0;j<2;j++)
{
int step=LS_Matrix[i];
int m;
for(m=step;m<28;m++)
{
temp[m-step]=pkey[m+j*28];
}
while(step)
{
temp[28-step]=pkey[m-28+j*28];
step--;
m++;
}
for(int k=0;k<28;k++)
{
pkey[k+j*28]=temp[k];
}
}
return;
}
//密码PC-1计算
void PC1(char s[],char t[])
{
//密码格式转换
char temp[64];
//方案一
/*for(int i=0;i<7;i++)
{
for(int j=0;j<8;j++)
{
temp[i*8+7-j] = (s[i] & (1 << j )) == 0 ? 0 : 1;
}
}
for(int i=7;i>=0;i--)
{
for(int j=6;j>=0;j--)
{
temp[i*8+j]=temp[i*7+j];
}
}*/
//方案二
for(int i=0;i<8;i++)
{
for(int j=0;j<8;j++)
{
temp[i*8+7-j] = (s[i] & (1 << j )) == 0 ? 0 : 1;
}
}
//PC1
for(int i=0;i<8;i++)
{
for(int j=0;j<7;j++)
{
int foo=PC1_Matrix[i][j]-1;
t[i*7+j]=temp[foo];
}
}
return;
}
//产生每代密码子
void genKey(char key[],int i,char *keys)
{
LS(i,key);
//PC2转换
for(int i=0;i<8;i++)
{
for(int j=0;j<6;j++)
{
int lo=PC2_Matrix[i][j]-1;
keys[i*6+j]=key[lo];
}
}
}
//做IP和IP_1转换
//参数:8*8byte数据的指针
//返回:直接在原数据上修改
void IP(char m[][8])
{
char temp[8][8];
for(int i=0;i<8;i++)
{
for(int j=0;j<8;j++)
{
int lo=IP_Matrix[i][j]-1;
temp[i][j]=m[lo/8][lo%8];
}
}
for(int i=0;i<8;i++)
{
for(int j=0;j<8;j++)
{
m[i][j]=temp[i][j];
}
}
return ;
}
//IP_1运算
void IP_1(char *pchar)
{
char temp[64];
for(int i=0;i<8;i++)
for(int j=0;j<8;j++)
{
temp[i*8+j]=pchar[IP_1_Matrix[i][j]-1];
}
for(int i=0;i<64;i++)
pchar[i]=temp[i];
}
//做E转换
//输入32byte数据s,放到48byte数据的目标t中
void E(char *s,char *t)
{
for(int i=0;i<8;i++)
{
for(int j=0;j<6;j++)
{
t[i*6+j]=s[E_Matrix[i][j]-1];
}
}
}
//将输入的16个char数据转换成64byte
void convertM(const char s[],char t[][8])
{
for(int i=0;i<8;i++)
{
for(int j=0;j<8;j++)
{
t[i][7-j] = (s[i] & (1 << j )) == 0 ? 0 : 1;
}
}
return;
}
//打印中间计算结果
void cc(char aa[8],char rr[])
{
rr[0]=(aa[0]<<3)+(aa[1]<<2)+(aa[2]<<1)+aa[3]+0x30;
if(rr[0]>0x39)rr[0]+=7;
rr[1]=(aa[4]<<3)+(aa[5]<<2)+(aa[6]<<1)+aa[7]+0x30;
if(rr[1]>0x39)rr[1]+=7;
return;
}
void printMatrix(char * step,char m[][8])
{
char foo[2];
printf("Now Step: %s End,Results are \n",step);
for(int i=0;i<8;i++)
{
for(int j=0;j<8;j++)
{
printf("%d ",m[i][j]);
}
cc(m[i],foo);
printf("\t%c %c\n",foo[0],foo[1]);
}
return;
}
//打印密码
void printKey(char keys[][48])
{
for(int i=0;i<16;i++)
{
printf("\tKey(%d): ",i+1);
for(int m=0;m<6;m++)
{
for(int j=0;j<8;j++)
printf("%d",keys[i][m*8+j]);
printf(" ");
}
printf("\n");
}
return;
}
//打印CD
void printCD(int i,char *key)
{
printf("C(%2d): ",i);
for(int m=0;m<28;m++)
printf("%d",key[m]);
printf("\t");
printf("D(%2d): ",i);
for(int m=28;m<56;m++)
printf("%d",key[m]);
printf("\n");
return;
}
//打印中间步骤
void printMid(char * ss,char* s,int len)
{
printf("\tAfter %s\t",ss);
for(int i=0;i<len/4;i++)
{
for(int j=0;j<4;j++)
{
printf("%d",s[i*4+j]);
}
printf(" ");
}
printf("\n");
}
//算法核心函数f
void f(char* R,char* key)
{
char temp48[48],temp32[32];
//对L做E转换,成48bit
E(R,temp48);
printMid("E",temp48,48);
//temp与key做+运算
for(int i=0;i<48;i++)
{
temp48[i]=temp48[i]^key[i];
}
printMid("E+k",temp48,48);
//S转换
for(int i=0;i<8;i++)
{
int row=0,vol=0,temp=0;
row=temp48[i*6+0]*2+temp48[i*6+5];
vol=temp48[i*6+1]*8+temp48[i*6+2]*4+temp48[i*6+3]*2+temp48[i*6+4];
temp=S_Box[i][row*16+vol];
for(int j=0;j<4;j++)
{
temp32[i*4+j]=(temp&(1<<(3-j)))==0?0:1;
}
}
printMid("S",temp32,32);
//P转换
for(int i=0;i<32;i++)
{
R[i]=temp32[P_Matrix[i]-1];
}
}
//每一轮函数
void roll(char *L,char *R,char *key)
{
char temp[32]={};
for(int i=0;i<32;i++)
temp[i]=R[i];
f(R,key);
printMid("f()",R,32);
//R=L+f;
for(int i=0;i<32;i++)
{
R[i]=L[i]^R[i];
}
printMid("R=L^R",R,32);
//L=R;
for(int i=0;i<32;i++)
L[i]=temp[i];
printMid("L=R",L,32);
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
int foo;
char m[8][8];//用于计算的64byte数据
char inputM[9] = "computer";//输入的8个char表示
char c[8][8];//64byte密文
char outputC[9];//用于输出的64bit密码的字符串表示
char inputK[9]="security";//密码
char key[48];//参与计算的密码中间数
char keys[16][48];//保留的密码子
//密码PC1计算
PC1(inputK,key);
printCD(0,key);
//经过16轮计算产生16个密码子
for(int i=0;i<16;i++)
{
genKey(key,i,keys[i]);
printCD(i+1,key);
}
printKey(keys);
//加密
printf("Start Encoding\n");
//转换数据,便于计算
convertM(inputM,m);
printMatrix("Input",m);
//做IP运算
IP(m);
printMatrix("After IP",m);
//开始做16轮循环
for(int i=0;i<16;i++)
{
roll(&m[0][0],&m[4][0],keys[i]);
char s[3];
sprintf(s,"%d",i+1);
printMatrix(s,m);
}
//处理最后多余的一次左右转换
char temp[32]={};
char *L=&m[0][0],*R=&m[4][0];
for(int i=0;i<32;i++)
{
temp[i]=L[i];
L[i]=R[i];
R[i]=temp[i];
}
IP_1(&m[0][0]);
printMatrix("End of Encoding",m);
//解密
puts("Start Decoding");
IP(m);
for(int i=15;i>=0;i--)
roll(&m[0][0],&m[4][0],keys[i]);
for(int i=0;i<32;i++)
{
temp[i]=L[i];
L[i]=R[i];
R[i]=temp[i];
}
IP_1(&m[0][0]);
printMatrix("End of Decoding",m);
scanf("%d",&foo);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -