DES数据加密算法
//DES算法加密 #include<iostream> #include<math.h> using namespace std; char * str2bin(char *str){//将16位16进制码转换为64位二进制码(不足8位高位补0) int i; char *st2; st2=(char*)malloc(sizeof(char)*65); st2[0]='\0'; for(i=0;i<16;i++){ switch(str[i]){ case '0':strcat(st2,"0000");break; case '1':strcat(st2,"0001");break; case '2':strcat(st2,"0010");break; case '3':strcat(st2,"0011");break; case '4':strcat(st2,"0100");break; case '5':strcat(st2,"0101");break; case '6':strcat(st2,"0110");break; case '7':strcat(st2,"0111");break; case '8':strcat(st2,"1000");break; case '9':strcat(st2,"1001");break; case 'A':strcat(st2,"1010");break; case 'B':strcat(st2,"1011");break; case 'C':strcat(st2,"1100");break; case 'D':strcat(st2,"1101");break; case 'E':strcat(st2,"1110");break; case 'F':strcat(st2,"1111");break; } } st2[64]='\0'; return st2; } char * bin2str(char *st2){//将64位二进制码转换为16位16进制码 int i,j; char *st; int a[]={8,4,2,1}; int buf; st=(char*)malloc(sizeof(char)*17); for(i=0;i<16;i++){ buf=0; for(j=0;j<4;j++){ buf=buf+(st2[i*4+j]=='1'? a[j]:0); } switch(buf){ case 0: st[i]='0';break; case 1: st[i]='1';break; case 2: st[i]='2';break; case 3: st[i]='3';break; case 4: st[i]='4';break; case 5: st[i]='5';break; case 6: st[i]='6';break; case 7: st[i]='7';break; case 8: st[i]='8';break; case 9: st[i]='9';break; case 10: st[i]='A';break; case 11: st[i]='B';break; case 12: st[i]='C';break; case 13: st[i]='D';break; case 14: st[i]='E';break; case 15: st[i]='F';break; } } st[16]='\0'; return st; } char * chushizhihuan(char *strb){//1.初始置换 char *stra; int i; stra=(char*)malloc(sizeof(char)*65); int a[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}; for(i=0;i<64;i++) stra[i]=strb[a[i]]; stra[i]='\0'; return stra; } char* miyuezhihuan(char *keyb){//3.密钥置换 char *keya; int i; keya=(char*)malloc(sizeof(char)*57); int a[]={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, 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}; for(i=0;i<56;i++){ keya[i]=keyb[a[i]]; } keya[i]='\0'; return keya; } void miyuezuoyi(char *keyb,int n){//4.第n轮密钥左移 char *temp; int a[]={1,1,2,2,2,2,2,2, 1,2,2,2,2,2,2,1}; temp=(char*)malloc(sizeof(char)*57); //保存将要循环移动到右边的位 memcpy(temp,keyb,a[n]); memcpy(temp+a[n],keyb+28,a[n]); //前28位移动 memcpy(keyb,keyb+a[n],28-a[n]); memcpy(keyb+28-a[n],temp,a[n]); //后28位移动 memcpy(keyb+28,keyb+28+a[n],28-a[n]); memcpy(keyb+56-a[n],temp+a[n],a[n]); } char * miyueyasuozhihuan(char *key){//5.密钥压缩置换(产生子密钥) int i; char *keybuf; keybuf=(char*)malloc(sizeof(char)*49); int a[]={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<48;i++){ keybuf[i]=key[a[i]]; } keybuf[i]='\0'; return keybuf; } char * kuozhanzhihuan(char *st){//6.扩展置换 int i; char *stbuf; stbuf=(char*)malloc(sizeof(char)*49); int a[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}; for(i=0;i<48;i++) stbuf[i]=st[a[i]]; stbuf[i]='\0'; return stbuf; } void yihuoyunsuan(char * str,char *key,int n){//7.异或运算 int i; for(i=0;i<n;i++){ str[i]=(str[i]==key[i])? '0':'1'; } } int bin2int(char *bin){ int i; int Int; Int=0; for(i=0;i<strlen(bin);i++) if(bin[i]=='1') Int=Int+pow(2,strlen(bin)-i-1); return Int; } char *int2bin(int Int){ char *bin; int key; int i; key=8; bin=(char*)malloc(sizeof(char)*5); for(i=0;i<4;i++){ bin[i]=(key&Int)? '1':'0' ; key>>=1; } bin[4]='\0'; return bin; } char* Shedaiti(char *strb){//8.S盒代替 int i,j; char *stra; char *hang; char *lie; stra=(char *)malloc(sizeof(char)*33); hang=(char *)malloc(sizeof(char)*3); lie=(char *)malloc(sizeof(char)*5); stra[0]='\0'; int s[8][4][16]=//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}}}; for(i=0;i<8;i++){ hang[0]=strb[i*6]; hang[1]=strb[i*6+5]; hang[2]='\0'; for(j=0;j<4;j++) lie[j]=strb[i*6+j+1]; lie[j]='\0'; strcat(stra,int2bin(s[i][bin2int(hang)][bin2int(lie)])); } return stra; } char *Phezhihuan(char *strb){//9.P盒置换 char *stra; stra=(char*)malloc(sizeof(char)*33); int i; int P[]= {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<32;i++) stra[i]=strb[P[i]]; stra[i]='\0'; return stra; } char *hebing(char *strl,char *strr){//13.合并 char *str; str=(char*)malloc(sizeof(char)*65); strcpy(str,strl); strcat(str,strr); return str; } char* nichushizhihuan(char *strb){//13.逆初始置换 char *stra; int i; stra=(char*)malloc(sizeof(char)*65); int a[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}; for(i=0;i<64;i++){ stra[i]=strb[a[i]]; } stra[i]='\0'; return stra; } int swap(char *left, char *right){ char *temp; temp=(char *)malloc(sizeof(char)*33); memcpy(temp,left,32); memcpy(left,right,32); memcpy(right,temp,32); return 0; } int main(){ int j; char *str_Ox; char *str_64; char *str_R_48; char *key_Ox; char *key_56; char *key_48; str_Ox = (char*)malloc(sizeof(char)*17); str_64 = (char*)malloc(sizeof(char)*65); str_R_48 = (char*)malloc(sizeof(char)*49); key_Ox = (char*)malloc(sizeof(char)*17); key_56 = (char*)malloc(sizeof(char)*57); key_48 = (char*)malloc(sizeof(char)*49);while(scanf("%s %s",key_Ox,str_Ox)!=EOF){//获取16位16进制密钥和16位16进制原文 key_56 = miyuezhihuan(str2bin(key_Ox));//将字符密钥转换为01密钥并执行密钥置换 str_64 = chushizhihuan(str2bin(str_Ox));//将字符原文转换为01原文并执行初始置换 for(j=0;j<16;j++){ memcpy(str_R_48,str_64+32,33);//分组 miyuezuoyi(key_56,j);//4.密钥左移 key_48 = miyueyasuozhihuan(key_56);//5.密钥压缩置换 str_R_48 = kuozhanzhihuan(str_R_48);//6.扩展置换 yihuoyunsuan(str_R_48,key_48,48);//7.48位异或运算 str_R_48 = Shedaiti(str_R_48);//8.S盒代替 str_R_48 = Phezhihuan(str_R_48);//9.P盒置换 yihuoyunsuan(str_64,str_R_48,32);//10.32位异或运算 if(j!=15){ swap(str_64,str_64+32); } } str_64 = nichushizhihuan(str_64); str_Ox = bin2str(str_64); printf("%s\n",str_Ox); } return 0; }
测试数据:
key plaintext ciphertext
0000000000000000 0000000000000000 8CA64DE9C1B123A7
FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF 7359B2163E4EDC58
3000000000000000 1000000000000001 958E6E627A05557B
1111111111111111 1111111111111111 F40379AB9E0EC533
0123456789ABCDEF 1111111111111111 17668DFC7292532D
1111111111111111 0123456789ABCDEF 8A5AE1F81AB8F2DD
0000000000000000 0000000000000000 8CA64DE9C1B123A7
FEDCBA9876543210 0123456789ABCDEF ED39D950FA74BCC4
7CA110454A1A6E57 01A1D6D039776742 690F5B0D9A26939B
0131D9619DC1376E 5CD54CA83DEF57DA 7A389D10354BD271
07A1133E4A0B2686 0248D43806F67172 868EBB51CAB4599A
3849674C2602319E 51454B582DDF440A 7178876E01F19B2A
04B915BA43FEB5B6 42FD443059577FA2 AF37FB421F8C4095
0113B970FD34F2CE 059B5E0851CF143A 86A560F10EC6D85B
0170F175468FB5E6 0756D8E0774761D2 0CD3DA020021DC09
43297FAD38E373FE 762514B829BF486A EA676B2CB7DB2B7A
07A7137045DA2A16 3BDD119049372802 DFD64A815CAF1A0F
04689104C2FD3B2F 26955F6835AF609A 5C513C9C4886C088
37D06BB516CB7546 164D5E404F275232 0A2AEEAE3FF4AB77
1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A
584023641ABA6176 004BD6EF09176062 88BF0DB6D70DEE56
025816164629B007 480D39006EE762F2 A1F9915541020B56
49793EBC79B3258F 437540C8698F3CFA 6FBF1CAFCFFD0556
4FB05E1515AB73A7 072D43A077075292 2F22E49BAB7CA1AC
49E95D6D4CA229BF 02FE55778117F12A 5A6B612CC26CCE4A
018310DC409B26D6 1D9D5C5018F728C2 5F4C038ED12B2E41
1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793
0101010101010101 0123456789ABCDEF 617B3A0CE8F07100
1F1F1F1F0E0E0E0E 0123456789ABCDEF DB958605F8C8C606
E0FEE0FEF1FEF1FE 0123456789ABCDEF EDBFD1C66C29CCC7
0000000000000000 FFFFFFFFFFFFFFFF 355550B2150E2451
FFFFFFFFFFFFFFFF 0000000000000000 CAAAAF4DEAF1DBAE
0123456789ABCDEF 0000000000000000 D5D44FF720683D0D
FEDCBA9876543210 FFFFFFFFFFFFFFFF 2A2BB008DF97C2F2
16轮循环每轮输出:
key plaintext ciphertext
636F6D7075746572 6C6561726E696E67 894CB732DF9DE103
1 : 00000000111111110111000111011000 00110101001100010011101110100101
2 : 00110101001100010011101110100101 00010111111000101011101010000111
3 : 00010111111000101011101010000111 00111110101100110000101110100100
4 : 00111110101100110000101110100100 01110101110101111111111001111111
5 : 01110101110101111111111001111111 11000110010111111000011111011100
6 : 11000110010111111000011111011100 10000101010110000011001100111011
7 : 10000101010110000011001100111011 01100110001001101001011100001100
8 : 01100110001001101001011100001100 00101111111110101000001000011110
9 : 00101111111110101000001000011110 11111001001100100010101111011100
10 : 11111001001100100010101111011100 00111010111011011011000101101101
11 : 00111010111011011011000101101101 01000101000011011111111001101000
12 : 01000101000011011111111001101000 01000010110010000011101001000010
13 : 01000010110010000011101001000010 01111001111111000011101001111111
14 : 01111001111111000011101001111111 00100000111001001100111010111001
15 : 00100000111001001100111010111001 01110101010011000011001110011100
16 : 01110101010011000011001110011100 01010010001111000011011011110101