呓语 | 杨英明的个人博客

专注于c++、Python,欢迎交流

By

DES加密算法实现

  好久没写博客了,正好趁着实现网络工程与安全的DES算法的功夫,把代码发上来。

  DES的介绍可见:DES加密

  原理不赘述了。。实在太多,其实就是一个形式化算法,按部就班的实现就可以,只不过有些繁琐,我写了3个晚上 = =。

  主要实现了利用DES算法对一个文本文档加密,然后再将其内容解密。

程序截图

  明文和密钥

 

  加密然后解密

 

  密文和解密后文本

 

代码

  1 //该程序实现了文本文档的DES加密和解密。
  2 
  3 #include <iostream>
  4 #include <string.h>
  5 #include <stdio.h>
  6 #include <stdlib.h>
  7 using namespace std;
  8 
  9 //IP置换表
 10 char IP[64] = {
 11     57,49,41,33,25,17,9,1,  
 12     59,51,43,35,27,19,11,3,  
 13     61,53,45,37,29,21,13,5,  
 14     63,55,47,39,31,23,15,7,  
 15     56,48,40,32,24,16,8,0,  
 16     58,50,42,34,26,18,10,2,  
 17     60,52,44,36,28,20,12,4,  
 18     62,54,46,38,30,22,14,6};   
 19 
 20 //IP^-1 置换表
 21 char IP_1[64] = {
 22     39,7,47,15,55,23,63,31,  
 23     38,6,46,14,54,22,62,30,  
 24     37,5,45,13,53,21,61,29,  
 25     36,4,44,12,52,20,60,28,  
 26     35,3,43,11,51,19,59,27,  
 27     34,2,42,10,50,18,58,26,  
 28     33,1,41,9,49,17,57,25,  
 29     32,0,40,8,48,16,56,24}; 
 30     
 31 //扩展置换表E  
 32 int E[48] = {31, 0, 1, 2, 3, 4,  
 33               3, 4, 5, 6, 7, 8,  
 34               7, 8,9,10,11,12, 
 35               11,12,13,14,15,16,  
 36               15,16,17,18,19,20,  
 37               19,20,21,22,23,24,  
 38               23,24,25,26,27,28,  
 39               27,28,29,30,31, 0};  
 40   
 41 //置换函数P  
 42 int P[32] = {15,6,19,20,28,11,27,16,  
 43               0,14,22,25,4,17,30,9,  
 44               1,7,23,13,31,26,2,8,  
 45               18,12,29,5,21,10,3,24};  
 46   
 47 //S盒  
 48 int S[8][4][16] ={
 49              {{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7},  
 50               {0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8},  
 51              {4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0},  
 52              {15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}},  
 53 
 54               {{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10},  
 55               {3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5},  
 56               {0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15},  
 57               {13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}},  
 58 
 59               {{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8},  
 60               {13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},  
 61               {13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7},  
 62               {1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}},  
 63 
 64               {{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15},  
 65               {13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9},  
 66               {10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4},  
 67               {3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}},  
 68 
 69               {{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9},  
 70               {14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6},  
 71               {4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14},  
 72               {11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}},  
 73 
 74               {{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11},  
 75               {10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8},  
 76               {9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6},  
 77               {4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}},  
 78 
 79               {{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1},  
 80               {13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6},  
 81               {1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2},  
 82               {6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}},  
 83 
 84               {{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7},  
 85               {1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2},  
 86               {7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8},  
 87               {2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}}};  
 88 //置换选择1  
 89 int PC_1[56] = {56,48,40,32,24,16,8,  
 90               0,57,49,41,33,25,17,  
 91               9,1,58,50,42,34,26,  
 92               18,10,2,59,51,43,35,  
 93               62,54,46,38,30,22,14,  
 94               6,61,53,45,37,29,21,  
 95               13,5,60,52,44,36,28,  
 96               20,12,4,27,19,11,3};  
 97   
 98 //置换选择2  
 99 int PC_2[48] = {13,16,10,23,0,4,2,27,  
100               14,5,20,9,22,18,11,3,  
101               25,7,15,6,26,19,12,1,  
102               40,51,30,36,46,54,29,39,  
103               50,44,32,47,43,48,38,55,  
104               33,52,45,41,49,35,28,31};  
105   
106 //对左移次数的规定  
107 int LS[17] = {0,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}; 
108 
109 //存放子密钥
110 unsigned __int64 K[17];
111 
112 //将含64个二进制字符的字符串转换为二进制形式存储在long long int中
113 unsigned __int64 str2bit(unsigned char s[])
114 {
115     unsigned __int64 bin = 0;
116     int i;
117     for(i=0;i<64;i++){
118         bin = bin<<1 | (s[i]-'0');    //s[i]>>j & 1 表示取s[i]的第j位
119     }
120     return bin;
121 }
122 
123 //将含8位字符串转换为二进制形式存储在long long int中,例ABCDEFGH转换为64位二进制数
124 unsigned __int64 bstr2bit(unsigned char s[])
125 {
126     unsigned __int64 bin = 0;
127     int i,j;
128     for(i=0;i<8;i++){
129         for(j=0;j<8;j++){
130             bin = bin  |  ( (unsigned __int64)((s[i]>>j)%2) << (j+8*(7-i)) );    //将s[i]的第j位(低位开始)取出放到bin的对应位置
131         }
132     }
133     return bin;
134 }
135 
136 //将 unsigned __int64 形式的按十六进制串输出(64位有效的二进制数串)
137 void DisplayHex64(unsigned __int64 bin)
138 {
139     int i,t=0;
140     for(i=63;i>=0;i--){
141         t = t<<1 | ((bin>>i) & 1);
142         if(i%4==0){
143             if(0<=t && t<=9)
144                 printf("%d",t);
145             else if(10<=t && t<=15)
146                 printf("%c",65+t-10);
147             t=0;
148         }
149         if(i%8==0)
150             printf(" ");
151     }
152     printf("\n");
153 }
154 //将 unsigned __int64 形式的按十六进制串输出(48位有效的二进制数串)
155 void DisplayHex48(unsigned __int64 bin)
156 {
157     int i,t=0;
158     for(i=47;i>=0;i--){
159         t = t<<1 | ((bin>>i) & 1);
160         if(i%4==0){
161             if(0<=t && t<=9)
162                 printf("%d",t);
163             else if(10<=t && t<=15)
164                 printf("%c",65+t-10);
165             t=0;
166         }
167         if(i%8==0)
168             printf(" ");
169     }
170     printf("\n");
171 }
172 //将 unsigned __int64 形式的按十六进制串输出(32位有效的二进制数串)
173 void DisplayHex32(unsigned __int64 bin)
174 {
175     int i,t=0;
176     for(i=31;i>=0;i--){
177         t = t<<1 | ((bin>>i) & 1);
178         if(i%4==0){
179             if(0<=t && t<=9)
180                 printf("%d",t);
181             else if(10<=t && t<=15)
182                 printf("%c",65+t-10);
183             t=0;
184         }
185         if(i%8==0)
186             printf(" ");
187     }
188     printf("\n");
189 }
190 //将 unsigned __int64 形式的按十六进制串输出(28位有效的二进制数串)
191 void DisplayHex28(unsigned __int64 bin)
192 {
193     int i,t=0;
194     for(i=27;i>=0;i--){
195         t = t<<1 | ((bin>>i) & 1);
196         if(i%4==0){
197             if(0<=t && t<=9)
198                 printf("%d",t);
199             else if(10<=t && t<=15)
200                 printf("%c",65+t-10);
201             t=0;
202         }
203         if(i%8==0)
204             printf(" ");
205     }
206     printf("\n");
207 }
208 
209 //将 unsigned __int64 形式的二进制串和十六进制输出(64位有效的二进制数串)
210 void DisplayBin64(unsigned __int64 bin)
211 {
212     int i;
213     for(i=63;i>=0;i--){
214         printf("%d",(bin>>i) %2);
215     }
216     printf("\n");
217     DisplayHex64(bin);
218 }
219 
220 //将 unsigned __int64 形式的二进制串和十六进制输出(48位有效的二进制数串)
221 void DisplayBin48(unsigned __int64 bin)
222 {
223     int i;
224     for(i=47;i>=0;i--){
225         printf("%d",(bin>>i) %2);
226     }
227     printf("\n");
228     DisplayHex48(bin);
229 }
230 
231 //将 unsigned __int64 形式的二进制串和十六进制输出(32位有效的二进制数串)
232 void DisplayBin32(unsigned __int64 bin)
233 {
234     int i;
235     for(i=31;i>=0;i--){
236         printf("%d",(bin>>i) %2);
237     }
238     printf("\n");
239     DisplayHex32(bin);
240 }
241 
242 //将 unsigned __int64 形式的二进制串和十六进制输出(28位有效的二进制数串)
243 void DisplayBin28(unsigned __int64 bin)
244 {
245     int i;
246     for(i=27;i>=0;i--){
247         printf("%d",(bin>>i) %2);
248     }
249     printf("\n");
250     DisplayHex28(bin);
251 }
252 
253 
254 /* ------------------------------ 【1】初始置换IP ------------------------------
255  *        把明文顺序打乱重新排列,置换输出为64位,
256  *    数据置换后的第一位,第二位分别是原来的58、50位 
257  */
258 
259 unsigned __int64 InitReplace(unsigned __int64 bin)    //初始置换IP
260 {
261     unsigned __int64 t = 0;
262     int i;
263     for(i=0;i<64;i++){
264         t = t | ( (bin>>(63-IP[i])) %2) << (63-i);
265     }
266     return t;
267 }
268 
269 /* ------------------------------ 【2】将置换输出的64位数据分成左右两半 ------------------------------
270  *        左一半称为L0,右一半称为R0,各32位。
271  */
272 
273 void DivideLR(unsigned __int64 binip,unsigned __int64 &L0,unsigned __int64 &R0)    //将置换输出的64位数据分为L0(32位),R0(32位)两部分
274 {
275     unsigned __int64 one = 1;
276     L0 = binip >> 32;
277     R0 = binip % (one<<32);
278 }
279 
280 /* ------------------------------ 【3】计算函数的16轮迭代 ------------------------------
281  *        1~16轮加密迭代
282  */
283 
284 //置换选择1,64->56
285 unsigned __int64 FunPC_1(unsigned __int64 bink)
286 {
287     unsigned __int64 binpc_1 = 0;
288     int i;
289     for(i=0;i<56;i++)
290         binpc_1 |= ( (bink>>(63-PC_1[i])) %2) << (55-i);
291     return binpc_1;
292 }
293 
294 //获得第i轮C,D,即Ci-1,Di-1 ==> Ci,Di
295 void getNextCD(int i,unsigned __int64 &C,unsigned __int64 &D)
296 {
297     unsigned __int64 t=0,one=1;
298     t = C >> (28-LS[i]);
299     C = (C<<LS[i])%(one<<28);
300     C |= t;
301     t = D >> (28-LS[i]);
302     D = (D<<LS[i])%(one<<28);
303     D |= t;
304 }
305 
306 //置换选择2,56->48
307 unsigned __int64 FunPC_2(unsigned __int64 t)
308 {
309     //获得子密钥k
310     unsigned __int64 k=0;
311     int i;
312     for(i=0;i<48;i++)
313         k |= ( (t>>(55-PC_2[i])) %2) << (47-i);
314     return k;
315 }
316 
317 //子密钥生成
318 void ProduceK(unsigned __int64 bink)
319 {
320     unsigned __int64 binpc_1,one=1,C=0,D=0;
321     binpc_1 = FunPC_1(bink);    //置换选择1
322 
323     //分成2个28位
324     C = binpc_1 >> 28;
325     D = binpc_1 % (one << 28);
326 
327     int i;
328     for(i=1;i<=16;i++){
329         //确定子密钥K[i]
330         getNextCD(i,C,D);
331         printf("第%d轮:\n",i);
332         printf("C[%d] = ",i);
333         DisplayBin28(C);
334         printf("D[%d] = ",i);
335         DisplayBin28(D);
336         printf("\n");
337         
338         unsigned __int64 t=0;
339         t = ((C<<28) | D)%(one<<56);
340         K[i] = FunPC_2(t);    //进行置换选择2,将56位->48位子密钥
341     }
342 }
343 
344 //扩展置换E,32->48
345 unsigned __int64 FunE(unsigned __int64 R)
346 {
347     unsigned __int64 t = 0;
348     int i;
349     for(i=0;i<48;i++)
350         t |= ( (R>>(31-E[i])) %2) << (47-i);
351     return t;
352 }
353 
354 //S盒代换
355 unsigned __int64 FunS(unsigned __int64 RX)
356 {
357     int x,y,i;
358     unsigned __int64 one = 1,t,RS = 0;
359     for(i=0;i<8;i++){
360         t = ( RX >> (6*(7-i)) ) % (one<<6);
361         x = t>>5;
362         x = (x<<1) | (t%2);
363         y = (t<<1)%(one<<6)>>2;
364         RS = RS<<4 | S[i][x][y];
365     }
366     return RS;
367 }
368 
369 //置换P运算
370 unsigned __int64 FunP(unsigned __int64 RS)
371 {
372     unsigned __int64 RP = 0;
373     int i;
374     for(i=0;i<32;i++)
375         RP |= ( (RS>>(31-P[i])) %2) << (31-i);
376     return RP;
377 }
378 
379 //轮函数f(R,K)
380 unsigned __int64 f(int i,unsigned __int64 R,unsigned __int64 k)
381 {
382     unsigned __int64 RE,RX,RS,RP;
383     RE = FunE(R);    //将32位Ri-1扩展置换为48位
384     RX = RE ^ k;    //将48位RE与子密钥k异或运算
385     RS = FunS(RX);    //S盒代换
386     RP = FunP(RS);        //置换P运算
387     return RP;
388 }
389 
390 unsigned __int64 Iteration16(unsigned __int64 L0,unsigned __int64 R0)    //进行16次迭代计算
391 {
392     int i;
393     unsigned __int64 Ri = R0;
394     unsigned __int64 Li = L0;
395     printf("L0=");
396     DisplayBin32(L0);
397     printf("R0=");
398     DisplayBin32(R0);
399     printf("\n");
400     for(i=1;i<=16;i++){
401         printf("第%d轮加密:\n",i);
402         unsigned __int64 t = Ri;
403 
404         //轮函数
405         Ri = f(i,Ri,K[i]);
406         printf("f(R%d,K%d)=",i-1,i);
407         DisplayBin32(Ri);
408         
409         //Li-1和轮函数结果异或运算得到Ri
410         Ri = Li ^ Ri;
411         //轮函数运算结果即是Li
412         Li = t;
413 
414         //输出Li和Ri
415         printf("L%d=",i);
416         DisplayBin32(Li);
417         printf("R%d=",i);
418         DisplayBin32(Ri);
419         printf("\n");
420     }
421 
422     return Ri<<32 | Li;
423 }
424 
425 unsigned __int64 InverseIteration16(unsigned __int64 L0,unsigned __int64 R0)    //进行逆16次迭代计算,为解密过程
426 {
427     int i;
428     unsigned __int64 Ri = R0;
429     unsigned __int64 Li = L0;
430     printf("L0=");
431     DisplayBin32(L0);
432     printf("R0=");
433     DisplayBin32(R0);
434     printf("\n");
435     for(i=16;i>=1;i--){
436         printf("第%d轮加密:\n",17-i);
437         unsigned __int64 t = Ri;
438 
439         //轮函数
440         Ri = f(i,Ri,K[i]);
441         printf("f(R%d,K%d)=",i-1,i);
442         DisplayBin32(Ri);
443         
444         //Li-1和轮函数结果异或运算得到Ri
445         Ri = Li ^ Ri;
446         //轮函数运算结果即是Li
447         Li = t;
448 
449         //输出Li和Ri
450         printf("L%d=",i);
451         DisplayBin32(Li);
452         printf("R%d=",i);
453         DisplayBin32(Ri);
454         printf("\n");
455     }
456 
457     return Ri<<32 | Li;
458 }
459 
460 
461 
462 /* ------------------------------ 【4】逆初始置换IP^-1 ------------------------------
463  *        把数据打乱重排,产生64位密文。
464  */
465 
466 unsigned __int64 InverseInitReplace(unsigned __int64 bin)    //进行逆初始置换IP^-1
467 {
468     unsigned __int64 t = 0;
469     int i;
470     for(i=0;i<64;i++){
471         t = t | ( (bin>>(63-IP_1[i])) %2) << (63-i);
472     }
473     return t;
474 }
475 
476 void printOut(FILE* fo,unsigned __int64 bin)
477 {
478     char ans[8]={0},t=0;
479     int i,cnt=0;
480     for(i=63;i>=0;i--){
481         t = t<<1 | ((bin>>i)%2);
482         if(i%8==0){
483             ans[cnt++] = t;
484             t = 0;
485         }
486     }
487     fwrite(ans,1,8,fo);
488 }
489 
490 //加密函数
491 void Encryption()
492 {
493     //文件读入
494     FILE* fm = fopen(".\\Plaintext.txt","rb");    //明文文件 
495     FILE* fk = fopen(".\\key.txt","r");    //密钥文件
496     FILE* fo = fopen(".\\Ciphertext.txt","wb");    //密文文件
497 
498     if(fm==NULL){
499         printf("明文文件input.txt打开失败\n");
500     }
501     if(fk==NULL){
502         printf("密钥文件key.txt打开失败\n");
503     }
504     if(fo==NULL){
505         printf("加密后文件output.txt打开失败\n");
506     }
507 
508     unsigned char s[165]={0},key[65]={0};
509     int i;
510 
511     fscanf(fk,"%s",key);    //读取密钥
512 
513     while(fread(s,1,8,fm)){
514         printf("----------------------------------------------------------------------------\n");
515         printf("\n");
516         printf("当前读取的明文串为:\n");
517         printf("%s\n",s);
518         unsigned __int64 bin = bstr2bit(s);    //将加密串转换为2进制形式
519         printf("\n");
520         unsigned __int64 bink = str2bit(key);    //将密钥串转换为2进制形式
521         printf("\n");
522         
523         //输出
524         printf("\n");
525         printf("【输入】\n");
526         printf("输入的二进制明文串:\n");
527         DisplayBin64(bin);
528         printf("输入的二进制密钥串:\n");
529         DisplayBin64(bink);
530         printf("\n");
531 
532         //IP置换
533         printf("明文初始化置换后:\n");
534         unsigned __int64 binip = InitReplace(bin);
535         DisplayBin64(binip);
536         printf("\n");
537 
538         //获得L0,R0
539         printf("将明文分割为L0,R0两部分:\n");
540         unsigned __int64 L0,R0;
541         DivideLR(binip,L0,R0);    //将binip分割为L0和R0
542         //输出L0,R0
543         printf("L0为:");
544         DisplayBin32(L0);
545         printf("R0为:");
546         DisplayBin32(R0);
547         printf("\n");
548 
549         //生成16个子密钥,并输出
550         printf("--------------- 子密钥生成过程 ---------------\n");
551         memset(K,0,sizeof(K));
552         ProduceK(bink);
553         printf("生成的16个子密钥:\n");
554         for(i=1;i<=16;i++){
555             printf("K[%d]为 ",i);
556             DisplayBin48(K[i]);
557             //printf("\n");
558         }
559         printf("\n");
560 
561         //16次加密迭代
562         printf("---------------  16轮加密迭代 --------------- \n");
563         unsigned __int64 binIter = Iteration16(L0,R0);
564         printf("迭代加密后的结果:\n");
565         DisplayBin64(binIter);
566         printf("\n");
567 
568         //逆初始置换IP_1
569         unsigned __int64 binip_1 = InverseInitReplace(binIter);
570         printf("最后,逆初始置换:\n");
571         DisplayBin64(binip_1);
572         printf("\n");
573 
574         //输出最终加密结果
575         printf("【加密结果】\n明文 \"%s\" 的DES加密的结果为:\n",s);
576         DisplayBin64(binip_1);
577 
578         printf("\n");
579         printf("----------------------------------------------------------------------------\n");
580         printf("\n");
581 
582         //将加密结果写到加密文件中
583         printOut(fo,binip_1);
584 
585         memset(s,0,sizeof(s));
586     }
587     //文件关闭
588     fclose(fm);
589     fclose(fk);
590     fclose(fo);
591 }
592 
593 //解密函数
594 void Decryption()
595 {
596     //文件读入
597     FILE* fm = fopen(".\\Ciphertext.txt","rb");    //密文文件 
598     FILE* fk = fopen(".\\key.txt","r");    //密钥文件
599     FILE* fo = fopen(".\\DecrypPlaintext.txt","wb");    //解密后文件
600 
601     if(fm==NULL){
602         printf("密文文件 Ciphertext.txt 打开失败\n");
603     }
604     if(fk==NULL){
605         printf("密钥文件 key.txt 打开失败\n");
606     }
607     if(fo==NULL){
608         printf("解密后文件 DecrypPlaintext.txt 打开失败\n");
609     }
610 
611     unsigned char s[165]={0},key[65]={0};
612     int i;
613 
614     fscanf(fk,"%s",key);    //读取密钥
615 
616     while(fread(s,1,8,fm)){
617         printf("----------------------------------------------------------------------------\n");
618         printf("\n");
619         printf("当前读取的密文串为:\n");
620         printf("%s\n",s);
621         unsigned __int64 bin = bstr2bit(s);    //将密文串转换为2进制形式
622         printf("\n");
623         unsigned __int64 bink = str2bit(key);    //将密钥串转换为2进制形式
624         printf("\n");
625         
626         //输出
627         printf("----------------------------------------------------------------------------\n");
628         printf("\n");
629         printf("【输入】\n");
630         printf("输入的二进制密文串:\n");
631         DisplayBin64(bin);
632         printf("输入的二进制密钥串:\n");
633         DisplayBin64(bink);
634         printf("\n");
635 
636         //IP置换
637         printf("密文初始化置换后:\n");
638         unsigned __int64 binip = InitReplace(bin);
639         DisplayBin64(binip);
640         printf("\n");
641 
642         //获得L0,R0
643         printf("将密文分割为L0,R0两部分:\n");
644         unsigned __int64 L0,R0;
645         DivideLR(binip,L0,R0);    //将binip分割为L0和R0
646         //输出L0,R0
647         printf("L0为:");
648         DisplayBin32(L0);
649         printf("R0为:");
650         DisplayBin32(R0);
651         printf("\n");
652 
653         //生成16个子密钥,并输出
654         printf("--------------- 子密钥生成过程 ---------------\n");
655         memset(K,0,sizeof(K));
656         ProduceK(bink);
657         printf("生成的16个子密钥:\n");
658         for(i=1;i<=16;i++){
659             printf("K[%d]为 ",i);
660             DisplayBin48(K[i]);
661             //printf("\n");
662         }
663         printf("\n");
664 
665         //16次加密迭代
666         printf("---------------  16轮加密迭代 --------------- \n");
667         unsigned __int64 binIter = InverseIteration16(L0,R0);
668         printf("迭代解密后的结果:\n");
669         DisplayBin64(binIter);
670         printf("\n");
671 
672         //逆初始置换IP_1
673         unsigned __int64 binip_1 = InverseInitReplace(binIter);
674         printf("最后,逆初始置换:\n");
675         DisplayBin64(binip_1);
676         printf("\n");
677 
678         //输出最终加密结果
679         printf("【解密结果】\n密文 \"%s\" 的DES解密的结果为:\n",s);
680         DisplayBin64(binip_1);
681 
682         printf("\n");
683         printf("----------------------------------------------------------------------------\n");
684 
685         //将加密结果写到加密文件中
686         printOut(fo,binip_1);
687 
688         memset(s,0,sizeof(s));
689     }
690     //文件关闭
691     fclose(fm);
692     fclose(fk);
693     fclose(fo);
694 }
695 
696 int Menu(int &Case)
697 {
698     int in;
699 
700     FILE* fk = fopen(".\\key.txt","r");    //密钥文件
701     if(fk==NULL){
702         printf("密钥文件key.txt打开失败\n");
703     }
704 
705     unsigned char key[100];
706     fscanf(fk,"%s",key);    //读取密钥
707     unsigned __int64 bink = str2bit(key);    //将密钥串转换为2进制形式
708     printf("【%d】当前密钥(key)为:(二进制形式)\n",Case++);
709     DisplayBin64(bink);
710     printf("(密钥存储在 key.txt 中)\n");
711     printf("\n");
712 
713     printf("请选择,是使用DES算法加密还是解密?\n");
714     printf("(加密过程:Plaintext.txt => Ciphertext.txt\n");
715     printf(" 解密过程:Ciphertext.txt => DecrypPlaintext.txt )\n");
716     printf("[1] 加密\n");
717     printf("[2] 解密\n");
718     printf("[0] 退出程序\n");
719 
720     scanf("%d",&in);
721     getchar();
722     fflush(stdin);    //    清空缓冲区
723 
724     if(in==0 || in==1 || in==2){
725         return in;
726     }
727     else{
728         printf("输入错误,请重新输入!\n");
729         printf("\n");
730         printf("----------------------------------------------------------------------------\n");
731         printf("\n");
732         return -1;
733     }
734 }
735 
736 /*
737  * 主函数
738  */
739 int main()
740 {
741     int Case=1,in;
742     while(1){
743         in = Menu(Case);
744         switch(in){
745         case -1:    //输入错误,进入下次循环
746             break;
747         case 0:        //退出程序
748             printf("谢谢使用 :)\n");
749             return 0;
750         case 1:        //加密
751             Encryption();
752             break;
753         case 2:        //解密
754             Decryption();
755             break;
756         }
757     }
758     return 0;
759 }

 

Freecode : www.cnblogs.com/yym2013

##原创声明 **转载请注明:[呓语](http://www.yangyingming.com) » [DES加密算法实现](http://www.yangyingming.com/article/47)**