教学服务系统

 找回密码
 立即注册
搜索
查看: 644|回复: 2

信息计算2019级一班30号邓子龙

[复制链接]

7

主题

20

帖子

107

积分

注册会员

Rank: 2

积分
107
发表于 2022-6-1 23:25:46 | 显示全部楼层 |阅读模式
DES加密算法

回复

使用道具 举报

7

主题

20

帖子

107

积分

注册会员

Rank: 2

积分
107
 楼主| 发表于 2022-6-1 23:27:23 | 显示全部楼层
  1. ///DES算法加密
  2. #include<cstdio>
  3. #include<cstring>
  4. const int maxn=2e4;
  5. char mingwen[maxn],miwen[maxn],miyao[maxn];///输入的明文密文密钥
  6. int smbit[maxn],miyaobit[maxn],mibit[maxn],zhongbit[maxn];///明文,密文,密钥的二进制,与转换中需要作为媒介的
  7. int mip[maxn],rr[maxn],SYa[maxn],er[10];///mip经过ip初始置换得到rrE盒扩展后得到,SYas盒压缩得到,er在s盒的转换过程中使用
  8. int Left[maxn],Right[maxn];///左右两部分
  9. int miyaopc1[maxn],miyaopc2[maxn],c[maxn],d[maxn];///c,d密钥置换得到
  10. int zimi[16][maxn];///产生的子密钥
  11. int LL[17][64],RR[17][64],cnt;///用来记录每一次的左右部分
  12. int times,xz[]= {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}; ///循环左移位,times用来计算是第几次移位
  13. void init()///初始化
  14. {
  15.     times=cnt=0;
  16.     memset(c,0,sizeof(c));
  17.     memset(d,0,sizeof(d));
  18.     memset(LL,0,sizeof(LL));
  19.     memset(RR,0,sizeof(RR));
  20.     memset(mip,0,sizeof(mip));
  21.     memset(SYa,0,sizeof(SYa));
  22.     memset(zimi,0,sizeof(zimi));
  23.     memset(Left,0,sizeof(Left));
  24.     memset(Right,0,sizeof(Right));
  25.     memset(miyao,0,sizeof(miyao));
  26.     memset(mingwen,0,sizeof(mingwen));
  27.     memset(miyaopc1,0,sizeof(miyaopc1));
  28.     memset(miyaopc2,0,sizeof(miyaopc2));
  29.     memset(miyaobit,0,sizeof(miyaobit));
  30. }
  31. const int IP[]=///ip置换表,用1维存的原因是方便置换。下面的都一样
  32. {
  33.     58,50,42,34,26,18,10,2,
  34.     60,52,44,36,28,20,12,4,
  35.     62,54,46,38,30,22,14,6,
  36.     64,56,48,40,32,24,16,8,
  37.     57,49,41,33,25,17, 9,1,
  38.     59,51,43,35,27,19,11,3,
  39.     61,53,45,37,29,21,13,5,
  40.     63,55,47,39,31,23,15,7,
  41. };
  42. const int E[]=///扩展E盒
  43. {
  44.     32,1,2,3,4,5,
  45.     4,5,6,7,8,9,
  46.     8,9,10,11,12,13,
  47.     12,13,14,15,16,17,
  48.     16,17,18,19,20,21,
  49.     20,21,22,23,24,25,
  50.     24,25,26,27,28,29,
  51.     28,29,30,31,32,1,
  52. };
  53. const int P[]=///p盒置换表
  54. {
  55.     16,7,20,21,29,12,28,17,1,15,23,26,5,18,31,10,
  56.     2,8,24,14,32,27,3,9,19,13,30,6,22,11,4,25,
  57. };
  58. const int PC_1[]=///密钥置换选择PC_1盒
  59. {
  60.     57,49,41,33,25,17,9,1,58,50,42,34,26,18,
  61.     10,2,59,51,43,35,27,19,11,3,60,52,44,36,
  62.     63,55,47,39,31,23,15,7,62,54,46,38,30,22,
  63.     14,6,61,53,45,37,29,21,13,5,28,20,12,4,
  64. };
  65. const int PC_2[]=///密钥置换选择PC_2盒
  66. {
  67.     14,17,11,24,1,5,3,28,15,6,21,10,
  68.     23,19,12,4,26,8,16,7,27,20,13,2,
  69.     41,52,31,37,47,55,30,40,51,45,33,48,
  70.     44,49,39,56,34,53,46,42,50,36,29,32
  71. };
  72. const int S[8][4][16]=///8个s盒
  73. {
  74.     ///s1
  75.     14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,
  76.     0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,
  77.     4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,
  78.     15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13,
  79.     ///s2
  80.     15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,
  81.     3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,
  82.     0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,
  83.     13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9,
  84.     ///s3
  85.     10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,
  86.     13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,
  87.     13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,
  88.     1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12,
  89.     ///s4
  90.     7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,
  91.     13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,
  92.     10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,
  93.     3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14,
  94.     ///s5
  95.     2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,
  96.     14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,
  97.     4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,
  98.     11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3,
  99.     ///s6
  100.     12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,
  101.     10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,
  102.     9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,
  103.     4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13,
  104.     ///s7
  105.     4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,
  106.     13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,
  107.     1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,
  108.     6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12,
  109.     ///s8
  110.     13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,
  111.     1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,
  112.     7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,
  113.     2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11,
  114. };
  115. const int IP_1[]=///逆初始置换表
  116. {
  117.     40,8,48,16,56,24,64,32,
  118.     39,7,47,15,55,23,63,31,
  119.     38,6,46,14,54,22,62,30,
  120.     37,5,45,13,53,21,61,29,
  121.     36,4,44,12,52,20,60,28,
  122.     35,3,43,11,51,19,59,27,
  123.     34,2,42,10,50,18,58,26,
  124.     33,1,41,9,49,17,57,25,
  125. };
  126. //int smbit[]={0,0,0,1,0,1,0,0, 0,1,0,0,1,1,1,0, 1,1,0,1,0,1,0,0, 1,1,1,0,1,1,1,1,0,0,0,1,0,0,0,1, 0,0,1,0,1,1,0,0, 1,1,1,0,0,1,1,0, 0,0,0,0,1,1,1,0};
  127. void change(char s[],int flag)///转换为二进制,(验证正确)
  128. {
  129.     int l=0;
  130.     for(int i=0; i<8; i++)
  131.     {
  132.         int n=s[i],time=0;
  133.         memset(zhongbit,0,sizeof(zhongbit));
  134.         while(n!=0)
  135.         {
  136.             zhongbit[time++]=n%2;
  137.             n/=2;
  138.         }
  139.         if(flag==1)
  140.         {
  141.             for(int j=7; j>=0; j--)
  142.                 smbit[l++]=zhongbit[j];
  143.         }
  144.         else if(flag==2)
  145.         {
  146.             for(int j=7; j>=0; j--)
  147.                 miyaobit[l++]=zhongbit[j];
  148.         }
  149.     }
  150. }
  151. void fen()///将64bit的minip分为左右两部分(验证正确)
  152. {
  153.     for(int i=0; i<32; i++)
  154.     {
  155.         Left[i]=mip[i];
  156.         Right[i]=mip[32+i];
  157.     }
  158.     for(int i=0; i<32; i++)
  159.     {
  160.         LL[cnt][i]=Left[i];
  161.         RR[cnt][i]=Right[i];
  162.     }
  163.     cnt++;
  164. }
  165. void ipzhihuan()///第一次循环使用的ip置换,ip置换(验证正确)
  166. {
  167.     for(int i=0; i<64; i++)
  168.         mip[i]=smbit[IP[i]-1];///下标从0开始
  169.     fen();
  170.     memset(smbit,0,sizeof(smbit));
  171. }
  172. void EK()///E盒扩展(验证正确)
  173. {
  174.     memset(rr,0,sizeof(rr));
  175.     for(int i=0; i<48; i++)
  176.         rr[i]=Right[E[i]-1];///下标从0开始
  177. }
  178. void SY(int k)///异或及S盒压缩(验证正确)
  179. {
  180.     for(int i=0; i<48; i++)
  181.         rr[i]^=zimi[k][i];
  182.     int c=0;
  183.     for(int i=0; i<48; i++)
  184.     {
  185.         if((i+1)%6==0)///进入下个s盒
  186.         {
  187.             int w=(i+1)/6,h,l;///哪个盒,哪一行那一列
  188.             h=rr[i-5]*2+rr[i]*1;
  189.             l=rr[i-4]*8+rr[i-3]*4+rr[i-2]*2+rr[i-1]*1;
  190.             int ans=S[w-1][h][l];
  191.             int tt=0;
  192.             memset(er,0,sizeof(er));
  193.             while(ans)
  194.             {
  195.                 er[tt++]=ans%2;
  196.                 ans/=2;
  197.             }
  198.             for(int j=3; j>=0; j--)
  199.                 SYa[c++]=er[j];
  200.         }
  201.     }
  202. }
  203. void PHe()///P盒置换
  204. {
  205.     for(int i=0; i<32; i++)
  206.         Right[i]=Left[i]^SYa[P[i]-1];
  207.     for(int i=0; i<32; i++)
  208.         Left[i]=mip[32+i];
  209.     for(int i=0; i<32; i++)
  210.     {
  211.         mip[i]=Left[i];
  212.         mip[32+i]=Right[i];
  213.     }
  214.     fen();///分为左右两部分
  215. }
  216. void nizhihuan()///逆初始置换表(验证正确)
  217. {
  218.     for(int i=0; i<64; i++)
  219.         smbit[i]=mip[IP_1[i]-1];
  220. }
  221. void PC_1zhi()///置换选择pc1盒及循环移位(验证正确)
  222. {
  223.     if(times==0)///只有当是第一次的时候才会进行PC置换盒1
  224.     {
  225.         for(int i=0; i<56; i++)
  226.             miyaopc1[i]=miyaobit[PC_1[i]-1];///下标从0开始
  227.     }
  228.     for(int i=0; i<28; i++) ///分为两部分,循环移位
  229.     {
  230.         int ans=i+xz[times];
  231.         if(ans>27)
  232.             ans-=28;
  233.         c[i]=miyaopc1[ans];///得到前半部分
  234.         d[i]=miyaopc1[28+ans];///得到后半部分
  235.     }
  236.     for(int i=0; i<28; i++)
  237.     {
  238.         miyaopc1[i]=c[i];
  239.         miyaopc1[28+i]=d[i];
  240.     }
  241.     times++;
  242. }
  243. void PC_2zhi()///16轮置换,pc2盒得到子密钥(验证正确)
  244. {
  245.     for(int k=0; k<16; k++)
  246.     {
  247.         PC_1zhi();
  248.         for(int i=0; i<48; i++)
  249.             zimi[k][i]=miyaopc1[PC_2[i]-1];///将每一次产生的子密钥存下来
  250.     }
  251. }
  252. void zhuan()///将二进制转换成16进制密文
  253. {
  254.     int ans=0,l=0;
  255.     for(int i=0; i<64; i++)
  256.     {
  257.         if((i+1)%4==0)
  258.         {
  259.             ans=smbit[i-3]*8+smbit[i-2]*4+smbit[i-1]*2+smbit[i];
  260.             if(ans>9)
  261.                 miwen[l++]='A'+ans-10;
  262.             else
  263.                 miwen[l++]=ans+'0';
  264.             ans=0;
  265.         }
  266.     }
  267. }
  268. void jiami()///加密算法
  269. {
  270.     PC_2zhi();///子密钥产生(正确)
  271.     ipzhihuan();///ip置换(正确)
  272.     for(int i=0; i<16; i++)
  273.     {
  274.         EK();///E盒扩展(正确)
  275.         SY(i);///S盒压缩(正确)
  276.         PHe();///p盒置换
  277.     }
  278.     for(int i=0; i<32; i++)
  279.     {
  280.         mip[32+i]=LL[16][i];
  281.         mip[i]=RR[16][i];
  282.     }
  283.     nizhihuan();
  284.     zhuan();
  285. }
  286. void jiemi()
  287. {
  288.     cnt=0;
  289.     memset(LL,0,sizeof(LL));
  290.     memset(RR,0,sizeof(RR));
  291.     ipzhihuan();///ip置换(正确)
  292.     for(int i=0; i<16; i++)
  293.     {
  294.         EK();///E盒扩展(正确)
  295.         SY(15-i);///S盒压缩(正确)
  296.         PHe();///p盒置换
  297.     }
  298.     for(int i=0; i<32; i++)
  299.     {
  300.         mip[32+i]=LL[16][i];
  301.         mip[i]=RR[16][i];
  302.     }
  303.     nizhihuan();
  304. }
  305. int main()
  306. {
  307.     init();
  308.     printf("请输入8位明文:");
  309.     scanf("%s",mingwen);
  310.     change(mingwen,1);
  311.     printf("\n请输入8位密钥:");
  312.     scanf("%s",miyao);
  313.     change(miyao,2);
  314.     jiami();
  315.     printf("加密完成,得到十六进制密文:\n");
  316.     printf("%s\n",miwen);
  317.     jiemi();
  318.     printf("\n解密完成,得到明文:\n\n");
  319.     for(int i=0;i<64;i++)
  320.     {
  321.         if((i+1)%8==0)
  322.         {
  323.             int ans=smbit[i-7]*128+smbit[i-6]*64+smbit[i-5]*32+smbit[i-4]*16+smbit[i-3]*8+smbit[i-2]*4+smbit[i-1]*2+smbit[i];
  324.             printf("%c",ans);
  325.         }
  326.     }
  327.     printf("\n");
  328.     return 0;
  329. }
复制代码
回复

使用道具 举报

7

主题

20

帖子

107

积分

注册会员

Rank: 2

积分
107
 楼主| 发表于 2022-6-1 23:28:07 | 显示全部楼层

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

教学服务系统

GMT+8, 2025-9-20 00:05 , Processed in 0.017141 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表