DES密码算法

来源:互联网 发布:中国电信4g网络覆盖 编辑:程序博客网 时间:2024/04/30 22:36

// 此算法,输入是键盘上任意字符,利用字符的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;}}// 初始置换IPvoid 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[n][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];elseE[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];elseE[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]; elseP_R[i][j]=S_R[0][b-1];}else{if(b==0)P_R[i][j]=S_R[a-1][3];elseP_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=R0void 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_1void 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=R0if(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;}



0 0
原创粉丝点击