DES密码算法
2016-05-28 12:59
281 查看
// 此算法,输入是键盘上任意字符,利用字符的ASCII值进行计算,输出是字符型。
#include<iostream> #include<cstdio> #include<string.h> using namespace std; int IP[9][9]={0},Yuan[9][9]={0},Miwen[9][9]={0},Key[8][8]={0}; // IP --->初始置换的值 Yuan --->明文 Miwen --->密文 Key --->密钥 int Right[8][4]={0},Left[8][4]={0}; // Right ---右部分 Left ---左部分 int R_0[8][4]={0}; // 存放Right上一次的值 int E[8][6]={0}; // 存放E扩展后的值 存放与子密钥异或的值 int S_R[8][4]={0}; // 存放S盒置换后的值 int P_R[8][4]={0}; // 存放P置换后的值 int C[28],D[28],kz2[8][6],kz[8][7]; // kz2 为子密钥 char ZI[8]; // 存放密文的字符型 int P_Box[8][4]={ 16, 7, 20, 21, // P置换表 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 }; int pc1[8][7]={ 57, 49, 41, 33, 25, 17, 9, // PC-1置换表 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 }; int pc2[8][6]={ 14, 17, 11, 24, 1, 5, // PC-2置换表 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 }; int S_Box[8][4][16]= // S盒置换表 //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}; // 明文的ASCII值 转换为二进制 void B_change(int i,int temp) { int j,k; for(j=8;j>=1&&temp;j--) { k=temp%2; Yuan[i][j]=k; temp=temp/2; } } // 密钥的ASCII值 转换为二进制 void B_B(int i,int temp) { int j,k; for(j=7;j>=0&&temp;j--) { k=temp%2; Key[i][j]=k; temp=temp/2; } } // 初始置换IP void Zhuanhuan( ) { int i,j,k; for(i=1;i<=8;i++) { if(i<5) k=i*2; else k=2*(i-5)+1; for(j=1;j<=8;j++) IP[i][j]=Yuan[8-j+1][k]; } } //将初始置换IP分左右两部分 void Left_Right( ) { int i,j,k=1,n=1; for(i=0;i<8;i++) { if(k>=9) { n++; k=1; } for(j=0;j<4;j++) { Left[i][j]=IP [k]; Right[i][j]=IP[n+4][k]; k++; } } } //E 扩展 void E_Table( ) { int i,j; for(i=0;i<8;i++) { for(j=0;j<6;j++) { if(j==0) { if(i==0) E[i][j]=Right[7][3]; else E[i][0]=Right[i-1][3]; } else E[i][j]=Right[i][j-1]; if(j==5) { if(i==7) E[7][5]=Right[0][0]; else E[i][5]=Right[i+1][0]; } } } /* // 验证是否正确 cout<<"E扩展:"; for(i=0;i<8;i++) for(j=0;j<6;j++) cout<<E[i][j]<<" "; cout<<endl; */ } // 与子密钥异或 void Key_XOR( ) { int i,j; for(i=0;i<8;i++) for(j=0;j<6;j++) E[i][j]=E[i][j]^kz2[i][j]; /* // 验证是否正确 cout<<"E扩展与子密钥异或:"; for(i=0;i<8;i++) for(j=0;j<6;j++) cout<<E[i][j]<<" "; cout<<endl; */ } // S盒中的值 转换为二进制 void B_Dexchange(int i,int temp) { int j=0,k=0; for(j=3;j>=0;j--) { k=temp%2; S_R[i][j]=k; temp=temp/2; } } // S 盒置换 void S_Table() { int i,right,left,temp,j; for(i=0;i<8;i++) { // left 为s盒中第i个s表的行,right 为s盒中第i个s表的列 // temp 为s表中置换后的数,十进制 left=E[i][0]*2+E[i][5]; right=E[i][1]*8+E[i][2]*4+E[i][3]*2+E[i][4]; temp=S_Box[i][left][right]; B_Dexchange(i,temp); // 将S盒中的十进制数化为二进制数 } /* // 验证是否正确 cout<<"S盒压缩:"; for(i=0;i<8;i++) for(j=0;j<4;j++) cout<<S_R[i][j]<<" "; cout<<endl; */ } // P 置换 void P_Table() { int i,j,x,a,b; for(i=0;i<8;i++) { for(j=0;j<4;j++) { x=P_Box[i][j]; // P_BOX ---> P置换表 a=x/4; b=x%4; if(a==0) // P_R ---> 存P置换的值 S_R ---> S盒置换的值 { if(b==0) P_R[i][j]=S_R[0][0]; else P_R[i][j]=S_R[0][b-1]; } else { if(b==0) P_R[i][j]=S_R[a-1][3]; else P_R[i][j]=S_R[a][b-1]; } } } /* // 验证是否正确 cout<<"P置换:"; for(i=0;i<8;i++) for(j=0;j<4;j++) cout<<P_R[i][j]<<" "; cout<<endl; */ } // R1=L0与P扩展后的值异或 void Left_XOR( ) { int i,j; for(i=0;i<8;i++) for(j=0;j<4;j++) { R_0[i][j]=Right[i][j]; // 保存上一次Right的值 Right[i][j]=Left[i][j]^P_R[i][j]; } /* // 验证是否正确 cout<<"Right:"; for(i=0;i<8;i++) for(j=0;j<4;j++) cout<<Right[i][j]<<" "; cout<<endl; */ } // L1=R0 void L_R() { int i,j; for(i=0;i<8;i++) for(j=0;j<4;j++) Left[i][j]=R_0[i][j]; /* // 验证是否正确 cout<<"Left:"; for(i=0;i<8;i++) for(j=0;j<4;j++) cout<<Left[i][j]<<" "; cout<<endl; */ } // 当最后一次循环时,左右两部分交换 void R_L_R() { int i,j,t; for(i=0;i<8;i++) for(j=0;j<4;j++) { t=Right[i][j]; Right[i][j]=Left[i][j]; Left[i][j]=t; } /* // 输出结果,验证是否正确 cout<<"第16次Left:"; for(i=0;i<8;i++) for(j=0;j<4;j++) cout<<Left[i][j]<<" "; cout<<"\n第16次Right:"; for(i=0;i<8;i++) for(j=0;j<4;j++) cout<<Right[i][j]<<" "; cout<<endl; */ } // 逆置换IP_1 void Nizhihuan() { int i,j,k; for(i=0;i<8;i++) // Miwen ---> 密文 { if(i<4)// 第2 4 6 8 列 { k=i*2+2; for(j=0;j<4;j++) { Miwen[8-j][k]=Left[k-2][j]; Miwen[4-j][k]=Left[k-1][j]; } } else // 第1 3 5 7 列 { k=2*(i-4)+1; for(j=0;j<4;j++) { Miwen[8-j][k]=Right[k-1][j]; Miwen[4-j][k]=Right[k][j]; } } } } //第一次PC_1置换 void Key_PC1( ) { int i,j,x,y,tc=0,td=0; for(i=0;i<8;i++) { for(j=0;j<7;j++) { x=pc1[i][j]/8; y=pc1[i][j]%8; if(!y&&x) { if(i<4) C[tc++]=Key[x-1][y]; else D[td++]=Key[x-1][y]; } else { if(y&&x) y--; if(!x&&y) y--; if(i<4) C[tc++]=Key[x][y]; else D[td++]=Key[x][y]; } } } } // C D 左移 void zy(int x) { int i,j,tc,td; tc=C[0]; td=D[0]; for(i=0;i<27;i++) { C[i]=C[i+1]; D[i]=D[i+1]; } C[27]=tc;D[27]=td; if(!(x==1||x==2||x==9||x==16)) { tc=C[0]; td=D[0]; for(i=0;i<27;i++) { C[i]=C[i+1]; D[i]=D[i+1]; } C[27]=tc;D[27]=td; } for(i=0,tc=0;i<4;i++) for(j=0;j<7;j++) kz[i][j]=C[tc++]; for(i=4,td=0;i<8;i++) for(j=0;j<7;j++) kz[i][j]=D[td++]; } //PC_2置换 void PC_2() { int i,j,x,y; for(i=0;i<8;i++) { for(j=0;j<6;j++) { x=pc2[i][j]/7; y=pc2[i][j]%7; if(!y&&x) kz2[i][j]=kz[x-1][6]; else { if(y&&x) y--; if(!x&&y) y--; kz2[i][j]=kz[x][y]; } } } /* // 输出子密钥,验证是否正确 cout<<"子密钥:"; for(i=0;i<8;i++) for(j=0;j<6;j++) cout<<kz2[i][j]<<" "; cout<<endl; */ } // 求得子密钥函数 void Key_ki(int x) { zy(x); //左移 memset(kz2,0,sizeof(kz2)); PC_2(); //第二次置换 } // 输出密文( 字符型 ) void ZiFu() { int i,temp; for(i=1;i<=8;i++) { temp=Miwen[i][1]*128+Miwen[i][2]*64+Miwen[i][3]*32+Miwen[i][4]*16+Miwen[i][5]*8+Miwen[i][6]*4+Miwen[i][7]*2+Miwen[i][8]; ZI[i]=temp; cout<<ZI[i]; } } int main() { char a[9],b[9]; int i, temp,j; // 输入明文,密钥 这里是字符型 cout<<"输入明文(最多8个字符):\n"; gets(a); cout<<"输入密钥(最多8个字符):\n"; gets(b); // 得到明文字符的ASCII值,将ASCII值 转换为二进制 for(i=0;a[i]!='\0';i++) { temp=a[i]; B_change(i+1,temp); } // 密钥转换为二进制值 for(i=0;b[i]!='\0';i++) { temp=b[i]; B_B(i,temp); } /* // 这里是输入64位二进制 cout<<"输入原文:\n"; for(i=1;i<=8;i++) for(j=1;j<=8;j++) scanf("%d",&Yuan[i][j]); cout<<"输入密钥:\n"; for(i=0;i<8;i++) for(j=0;j<8;j++) scanf("%d",&Key[i][j]); */ /* // 验证是否正确 printf("\n输出明文(ASCII值,二进制):\n"); for(i=1;i<=8;i++) { for(j=1;j<=8;j++) printf("%d ",Yuan[i][j]); printf("\n"); } printf("\n输出密钥(ASCII值,二进制):\n"); for(i=0;i<8;i++) { for(j=0;j<8;j++) printf("%d ",Key[i][j]); printf("\n"); } printf("\n输出初始置换IP的值:\n"); for(i=1;i<=8;i++) { for(j=1;j<=8;j++) printf("%d ",IP[i][j]); printf("\n"); } */ Key_PC1( ); // 调用密钥函数,pc1置换 Zhuanhuan( ); // 调用初始置换IP函数 Left_Right( ); // 将IP分左右两部分 // 进行16轮迭代 for(i=1;i<=16;i++) { // cout<<"\n----------------------第"<<i<<"次--------------------------\n"; E_Table(); // E 扩展函数 Key_ki(i); // 求得子密钥 Key_XOR(); // 与子密钥异或 S_Table(); // S 盒置换 P_Table(); // P 置换 // L1=R0 R1=L0与P扩展后的值异或 Left_XOR(); L_R(); // L1=R0 if(i==16) R_L_R(); // 交换左右两部分的值 } Nizhihuan( ); // 调用初始逆置换函数 /* printf("\n输出密文(ASCII值,二进制):\n"); for(i=1;i<=8;i++) { for(j=1;j<=8;j++) printf("%d ",Miwen[i][j]); printf("\n"); } */ printf("\n输出密文(字符型):\n"); ZiFu(); cout<<endl; return 0; }
相关文章推荐
- MATLAB计算矩阵间的欧式距离(不用循环!)
- 结构体作为对象的属性
- Hadoop Serialize(二)
- Apache-Tomcat 和 Apache-Maven配置
- 有关i多线程编程的思考
- linux 部署tomcat
- Apache-Tomcat 和 Apache-Maven配置
- 如何训练自己的编程思路
- github简单使用教程
- Android Dialog 系统样式讲解及透明背景
- Spark streaming源码分析之Job动态生成原理与源码解析
- 软件测试作业四
- HDU 1017 A Mathematical Curiosity
- C++实验6-项目4:字符删除
- win10 内测14352 加入了容器 和docker新功能,想体验的赶快升级
- 注意资源利用 不然导致资源消耗会很严重
- centos mysql开启远程访问
- apply()函数族
- WindowsXP SP3 AFD.sys 本地拒绝服务漏洞的挖掘过程
- 打包压缩、解压缩工具详解