实验一一、实验名称:替代密码和置换密码的实现二、实验目的:通过编程实现替代密码算法和置换密码算法,加深对古典密码体系的了解,为以后深入学习密码学奠定基础。三、实验内容:A:替代密码1、实验原理:使用替代法进行加密,将明文中的字符用其他字符替代后形成密文。最早的替代密码是由JuliusCaesar发明的Caesar(恺撒)密码,又叫循环移位密码。它的加密过程可表示为:E(m)=(m+k)modn其中,m为明文字母在字母表中的位置数;n为字母表中的字母个数;k为密钥;E(m)为密文字母在字母表中对应的位置数。解密算法是:m=D(L)=(L-k)mod26;2、算法设计:使用两个函数分别进行加密和解密的过程,在主程序中通过选择加密还是解密来调用不同函数进行替代密码的加密和解密过程实现;3、函数接口:加密:intencrypt(){printf(输入明文:\n);scanf(%s,a);for(i=0;a[i]!='\0';i++){b[i]=a[i]-64;}printf(输入一位密钥\n);scanf(%d,&k);printf(\n);for(i=0;b[i]!='\0';i++){m[i]=(b[i]+k)%26+64;}printf(%s,&m);return0;}解密:intdecode(){printf(输入密文:\n);scanf(%s,a);for(i=0;a[i]!='\0';i++){b[i]=a[i]-64;}printf(输入一位密钥\n);scanf(%d,&k);printf(\n);for(i=0;b[i]!='\0';i++){n[i]=(b[i]-k)%26+64;}printf(%s,n);return0;}4、程序流程图:5、测试结果截图:加密:解密:B:1、实验原理:不改变明文字符,但是把字符在明文中的排列顺序改变,来实现明文信息的加密。置换密码也被称为换位密码。本次实验使用的是矩阵换位法,是将明文中的字母按照给定的顺序安排在一个矩阵中,然后又根据密钥提供的顺序重新组合矩阵中的字母,从而形成密文。解密过程是根据密钥的字母数作为列数,将密文按照列、行的顺序写出,再根据由密钥给出的矩阵置换产生新的矩阵恢复正常顺序,从而恢复明文。2、算法设计:通过选择加密或解密,使用置换矩阵顺序和恢复矩阵顺序的两个函数,分别在主函数中进行调用来实现置换密码的加密解密实现;3、函数接口:加密:intjiami(){inti=0,j=0,key_len=0,text_len=0,row=0;charkey[LENGTH]={0};charnumber[LENGTH]={0};charptext[LENGTH*10]={0};charctext[LENGTH*10]={0};printf(输入明文:\n);scanf(%s,ptext);i=0;while(ptext[i]!=0){text_len++;i++;}printf(输入密钥:\n);scanf(%s,key);i=0;while(key[i]!=0){key_len++;i++;}for(i=0;ikey_len;i++){number[i]=0;for(j=0;jkey_len;j++){if(key[j]key[i])number[i]++;}}for(i=0;ikey_len;i++){for(j=i+1;jkey_len;j++){if(key[j]==key[i])number[j]++;}}if(text_len%key_len==0)row=text_len/key_len;elserow=text_len/key_len+1;for(i=0;ikey_len;i++){for(j=0;jrow;j++){ctext[i*row+j]=ptext[number[i]+key_len*j];}}for(i=0;ikey_len;i++){for(j=0;jrow;j++){printf(%c,ctext[i*row+j]);}}return0;}解密:intjiemi(){inti=0,j=0,key_len=0,text_len=0,row=0;charkey1[LENGTH]={0};charptext1[LENGTH*10]={0};charctext1[LENGTH*10]={0};charnumber1[LENGTH]={0};printf(输入密文:\n);scanf(%s,ctext1);while(ctext1[i]!=0){text_len++;i++;}printf(输入密钥);scanf(%s,key1);i=0;while(key1[i]!=0){key_len++;i++;}for(i=0;ikey_len;i++){intj=0;number1[i]=0;for(j=0;jkey_len;j++){if(key1[j]key1[i])number1[i]++;}}for(i=0;ikey_len;i++){intj=0;for(j=i+1;jkey_len;j++){if(key1[j]==key1[i])number1[j]++;}}if(text_len%key_len==0)row=text_len/key_len;elserow=text_len/key_len+1;for(i=0;ikey_len;i++){for(j=0;jrow;j++){ptext1[number1[i]+key_len*j]=ctext1[i*row+j];}}for(i=0;ikey_len;i++){for(j=0;jrow;j++){printf(%c,ptext1[i*row+j]);}}return0;}4、程序流程图:5、测试结果截图:三、实验总结:1、在进行替代密码实现的时候,总是出现程序终止,然后一步步调试,还用了断点测试,最后发现是循环的终止条件设置错误,最后经过了改正,程序能够从正常运行;2、在进行置换实验的时候,设置的数组总是出错,数量不足或排序错误,感觉对这一方面的代码实现有很大的不足,置换数组方面忘记了很多概念,应该进行转么的复习;3、经过这一次的实验,对古典密码中的替代密码和置换密码有了一定的了解,感觉对于密码学有了很浓厚的兴趣,想要进一步了解一些密码的算法和实现的方法;4、感觉一个假期没有编程,忘记了很多语句和各种基本知识,感觉应该再系统地复习一遍,再多加练习。四、问题回答:替代密码:分析密文中的字母频率后将可以对照破解;可能严重偏离标准频率,加入文章少于100个字母,那么对它的解密就会比较困难。改进:在单一恺撒密码的基础上扩展出多表密码,称为维吉尼亚密码。引入了密钥的概念,即根据密钥来决定用哪一行的密表来进行替换,可以对抗字频统计。五、实验代码:A、替代密码:#includestdio.h#includeconio.h#includestring.hintk,i=0;chara[100];charb[100],m[100],n[100];intencrypt(){printf(输入明文:\n);scanf(%s,a);for(i=0;a[i]!='\0';i++){b[i]=a[i]-64;}printf(输入一位密钥\n);scanf(%d,&k);printf(\n);for(i=0;b[i]!='\0';i++){m[i]=(b[i]+k)%26+64;}printf(%s,&m);return0;}intdecode(){printf(输入密文:\n);scanf(%s,a);for(i=0;a[i]!='\0';i++){b[i]=a[i]-64;}printf(输入一位密钥\n);scanf(%d,&k);printf(\n);for(i=0;b[i]!='\0';i++){n[i]=(b[i]-k)%26+64;}printf(%s,n);return0;}intmain(){intc;printf(加密选择1,解密选择2\n);scanf(%d,&c);if(c==1){encrypt();}if(c==2){decode();}return0;}B、置换密码:#includestdio.h#includestring.h#defineLENGTH26intjiami(){inti=0,j=0,key_len=0,text_len=0,row=0;charkey[LENGTH]={0};charnumber[LENGTH]={0};charptext[LENGTH*10]={0};charctext[LENGTH*10]={0};printf(输入明文:\n);scanf(%s,ptext);i=0;while(ptext[i]!=0){text_len++;i++;}printf(输入密钥:\n);scanf(%s,key);i=0;while(key[i]!=0){key_len++;i++;}for(i=0;ikey_len;i++){number[i]=0;for(j=0;jkey_len;j++){if(key[j]key[i])number[i]++;}}for(i=0;ikey_len;i++){for(j=i+1;jkey_len;j++){if(key[j]==key[i])number[j]++;}}if(text_len%key_len==0)row=text_len/key_len;elserow=text_len/key_len+1;for(i=0;ikey_len;i++){for(j=0;jrow;j++){ctext[i*row+j]=ptext[number[i]+key_len*j];}}for(i=0;ikey_len;i++){for(j=0;jrow;j++){printf(%c,ctext[i*row+j]);}}return0;}intjiemi(){inti=0,j=0,key_len=0,text_len=0,row=0;charkey1[LENGTH]={0};charptext1[LENGTH*10]={0};charctext1[LENGTH*10]={0};charnumber1[LENGTH]={0};printf(输入密文:\n);scanf(%s,ctext1);while(ctext1[i]!=0){text_len++;i++;}printf(输入密钥);scanf(%s,key1);i=0;while(key1[i]!=0){key_len++;i++;}for(i=0;ikey_len;i++){intj=0;number1[i]=0;for(j=0;jkey_len;j++){if(key1[j]key1[i])number1[i]++;}}for(i=0;ikey_len;i++){intj=0;for(j=i+1;jkey_len;j++){if(key1[j]==key1[i])number1[j]++;}}if(text_len%key_len==0)row=text_len/key_len;elserow=text_len/key_len+1;for(i=0;ikey_len;i++){for(j=0;jrow;j++){ptext1[number1[i]+key_len*j]=ctext1[i*row+j];}}for(i=0;ikey_len;i++){for(j=0;jrow;j++){printf(%c,ptext1[i*row+j]);}}return0;}intmain(){inta;printf(加密选择1,解密选择2);scanf(%d,&a);if(a==1){jiami();}elseif(a==2){jiemi();}return0;}