首页 > 编程知识 正文

des加密算法例题,des算法基本过程

时间:2023-05-04 12:48:00 阅读:168447 作者:3309

这几天,老师布置了作业写。 主要是DES算法的加密。 我自由地写了。 这里实现了明文8字节的加密和通过加密对密文的解密。 不能直接输入密文。

请自己百度学习一下什么是DES算法,这里只显示了实现代码。

虽然代码中的每个步骤都有说明,而且实现起来可能很麻烦,但为了清楚起见,代码应该如下所示:

///DES算法加密# include cstdio # includecstringconstintmaxn=2e 4; char mingwen[maxn]、miwen[maxn]、miyao[maxn]; //输入的明文加密密钥int smbit[maxn]、miyaobit[maxn]、mibit[maxn]、zhongbit[maxn]; //明文、密文、加密密钥二进制文件、作为转换媒介的int mip[maxn]、rr[maxn]、SYa[maxn]、er[10]; ///mip是经过ip初始置换,rrE框被扩展的,SYas框被压缩的,er是在s框的变换中输入left [ maxn ],Right[maxn]; //左右int miyaopc1[maxn]、miyaopc2[maxn]、c[maxn]、d[maxn]; 在//c,d键替换中输入int zimi[16][maxn]; //生成的子密钥int LL[17][64]、RR[17][64]、cnt; //每次的左右部分int times,xz [ ]={ 1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2 //循环左移,times表示第几次移位void init ()//初始化({ times=cnt=0; memset(c,0,sizeof(c ) c ); memset(d,0,sizeof(d ) d ); memset(ll,0,sizeof ) ll ); memset(RR,0,sizeof ) RR ); memset(MIP,0,sizeof ) MIP ); memset(sya,0,sizeof ) sya ); memset(zimi,0,sizeof ) zimi ); memset(left,0,sizeof ) left ); memset(right,0,sizeof ) right ); memset(miyao,0,sizeof ) miyao ); memset(mingwen,0,sizeof ) mingwen ); memset (miya OPC 1,0,sizeof ) miyaOPC1); memset (miya OPC 2,0,sizeof ) miyaOPC2); memset(miyaobit,0,sizeof ); }用}const int IP[]=///ip替换表,用一维保存的理由是替换容易。 下面的东西都一样。 {58、50、42、34、26、18、10、2、60、52、44、36、28、42、54、46、38、30、22、14、64、61、61 const int E[]=///扩展e框{ 32,1,2,3,4,5,4,5,5,6,7,8,9,10,11,12,13,12,13,15,15 } 2,8,24,14,32 } const int PC _1[ ]=//密钥替换PC_1框{ 57,49,41,33,25,17,9,58,50,42,34,26,26,} 5、3、28、15、6、21、10、23、19、12、4、26、8、const int S[8][4][16]=///8个s框{//s114、4、13、4、13

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,};const int IP_1[]=///逆初始置换表{ 40,8,48,16,56,24,64,32, 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,};//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};void change(char s[],int flag)///转换为二进制,(验证正确){ int l=0; for(int i=0; i<8; i++) { int n=s[i],time=0; memset(zhongbit,0,sizeof(zhongbit)); while(n!=0) { zhongbit[time++]=n%2; n/=2; } if(flag==1) { for(int j=7; j>=0; j--) smbit[l++]=zhongbit[j]; } else if(flag==2) { for(int j=7; j>=0; j--) miyaobit[l++]=zhongbit[j]; } }}void fen()///将64bit的minip分为左右两部分(验证正确){ for(int i=0; i<32; i++) { Left[i]=mip[i]; Right[i]=mip[32+i]; } for(int i=0; i<32; i++) { LL[cnt][i]=Left[i]; RR[cnt][i]=Right[i]; } cnt++;}void ipzhihuan()///第一次循环使用的ip置换,ip置换(验证正确){ for(int i=0; i<64; i++) mip[i]=smbit[IP[i]-1];///下标从0开始 fen(); memset(smbit,0,sizeof(smbit));}void EK()///E盒扩展(验证正确){ memset(rr,0,sizeof(rr)); for(int i=0; i<48; i++) rr[i]=Right[E[i]-1];///下标从0开始}void SY(int k)///异或及S盒压缩(验证正确){ for(int i=0; i<48; i++) rr[i]^=zimi[k][i]; int c=0; for(int i=0; i<48; i++) { if((i+1)%6==0)///进入下个s盒 { int w=(i+1)/6,h,l;///哪个盒,哪一行那一列 h=rr[i-5]*2+rr[i]*1; l=rr[i-4]*8+rr[i-3]*4+rr[i-2]*2+rr[i-1]*1; int ans=S[w-1][h][l]; int tt=0; memset(er,0,sizeof(er)); while(ans) { er[tt++]=ans%2; ans/=2; } for(int j=3; j>=0; j--) SYa[c++]=er[j]; } }}void PHe()///P盒置换{ for(int i=0; i<32; i++) Right[i]=Left[i]^SYa[P[i]-1]; for(int i=0; i<32; i++) Left[i]=mip[32+i]; for(int i=0; i<32; i++) { mip[i]=Left[i]; mip[32+i]=Right[i]; } fen();///分为左右两部分}void nizhihuan()///逆初始置换表(验证正确){ for(int i=0; i<64; i++) smbit[i]=mip[IP_1[i]-1];}void PC_1zhi()///置换选择pc1盒及循环移位(验证正确){ if(times==0)///只有当是第一次的时候才会进行PC置换盒1 { for(int i=0; i<56; i++) miyaopc1[i]=miyaobit[PC_1[i]-1];///下标从0开始 } for(int i=0; i<28; i++) ///分为两部分,循环移位 { int ans=i+xz[times]; if(ans>27) ans-=28; c[i]=miyaopc1[ans];///得到前半部分 d[i]=miyaopc1[28+ans];///得到后半部分 } for(int i=0; i<28; i++) { miyaopc1[i]=c[i]; miyaopc1[28+i]=d[i]; } times++;}void PC_2zhi()///16轮置换,pc2盒得到子密钥(验证正确){ for(int k=0; k<16; k++) { PC_1zhi(); for(int i=0; i<48; i++) zimi[k][i]=miyaopc1[PC_2[i]-1];///将每一次产生的子密钥存下来 }}void zhuan()///将二进制转换成16进制密文{ int ans=0,l=0; for(int i=0; i<64; i++) { if((i+1)%4==0) { ans=smbit[i-3]*8+smbit[i-2]*4+smbit[i-1]*2+smbit[i]; if(ans>9) miwen[l++]='A'+ans-10; else miwen[l++]=ans+'0'; ans=0; } }}void jiami()///加密算法{ PC_2zhi();///子密钥产生(正确) ipzhihuan();///ip置换(正确) for(int i=0; i<16; i++)///一样的方式一共循环15次 { EK();///E盒扩展(正确) SY(i);///S盒压缩(正确) PHe();///p盒置换 } for(int i=0; i<32; i++) { mip[32+i]=LL[16][i]; mip[i]=RR[16][i]; } nizhihuan(); zhuan();}void jiemi(){ cnt=0; memset(LL,0,sizeof(LL)); memset(RR,0,sizeof(RR)); ipzhihuan();///ip置换(正确) for(int i=0; i<16; i++)///一样的方式一共循环15次 { EK();///E盒扩展(正确) SY(15-i);///S盒压缩(正确) PHe();///p盒置换 } for(int i=0; i<32; i++) { mip[32+i]=LL[16][i]; mip[i]=RR[16][i]; } nizhihuan();}int main(){ init(); printf("请输入8位明文:"); scanf("%s",mingwen); change(mingwen,1); printf("n请输入8位密钥:"); scanf("%s",miyao); change(miyao,2); jiami(); printf("加密完成,得到十六进制密文:n"); printf("%sn",miwen); jiemi(); printf("n解密完成,得到明文:nn"); for(int i=0;i<64;i++) { if((i+1)%8==0) { 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]; printf("%c",ans); } } printf("n"); return 0;}

运行结果:

某网站在线加密运行结果:

结果除了大小写以及尾串不一样,其它相同,加密成功

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。