密码学课程设计.docx
- 文档编号:4426759
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:17
- 大小:141.14KB
密码学课程设计.docx
《密码学课程设计.docx》由会员分享,可在线阅读,更多相关《密码学课程设计.docx(17页珍藏版)》请在冰豆网上搜索。
密码学课程设计
密码学课程设计
《多表古典加密和解密程序》
姓名:
林良松
专业:
信息工程
班级:
1132101
学号:
201130210116
2014-1-11
一、实验目的:
掌握多表古典加密方法。
二、实验要求:
能用高级语言实现古典加密方法。
三、实验内容:
多表古典加密方法主要有Playfair体制、Vigenere体制、Beaufor体制、Vernam体制和Hill体制,用高级语言实现其中一种体制的加密和解密算法。
四、实验过程:
1、Vigenere加密解密:
维吉尼亚密码引入了“密钥”的概念,即根据密钥来决定用哪一行的密表来进行替换,以此来对抗字频统计。
#include
#include
usingnamespacestd;
constintN=26;
charv[N][N]={{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}};
intnumber(charx)//把行号字母对应到数字
{
chary='a';
for(inti=0;i { if(x==(y+i))returni; } } voidencryption(stringm,stringk)//加密 { cout<<"明文: "; cin>>m; cout<<"密钥: "; cin>>k; intmlen,klen; mlen=m.length(); klen=k.length(); char*p,*q,*t;//明文,初始密钥,密钥串。 把string换成char p=newchar[m.length()+1]; strcpy(p,m.c_str()); q=newchar[k.length()+1]; strcpy(q,k.c_str()); t=newchar[m.length()+1]; intj=0; for(inti=0;i { t[i]=q[j]; j++; j=j%klen; }//生成密钥 cout<<"密文: "; for(i=0;i cout< cout< } voiddisencryption(stringc,stringk)//解密 { cout<<"密文: "; cin>>c; cout<<"密钥: "; cin>>k; intclen,klen; clen=c.length(); klen=k.length(); char*p,*q,*t;//密文,初始密钥,密钥串。 把string换成char p=newchar[c.length()+1]; strcpy(p,c.c_str()); q=newchar[k.length()+1]; strcpy(q,k.c_str()); t=newchar[c.length()+1]; intj=0; for(inti=0;i { t[i]=q[j]; j++; j=j%klen; }//生成密钥 cout<<"明文: "; for(i=0;i for(intj=0;j if(v[number(t[i])][j]==p[i]){cout< cout< } intmain() { for(inti=1;i { for(intj=0;j { v[i][j]=v[i-1][(j+1)%N]; }//方阵初始化 } cout<<"欢迎使用Vigenere加密! "< cout<<"请选择要进行的操作"< intflag; do{ cout<<"1.加密2.解密3.结束: "< cin>>flag; stringm,k; if(flag==1)encryption(m,k); elseif(flag==2)disencryption(m,k); elseif(flag! =1&&flag! =2&&flag! =3)cout<<"输入错误,请重新输入! "; }while(flag! =3); return0; } 运行结果: 2、Playfair加解密 算法描述: Playfair密码出现于1854年,它依据一个5*5的正方形组成的密码表来编写,密码表里排列有25个字母。 如果一种语言字母超过25个,可以去掉使用频率最少的一个。 英语中z使用最少,可以去掉它。 法语一般去掉w或k,德语则是把i和j合起来当成一个字母看待。 英语中z使用最少,可以去掉它。 加密描述: 第一步是编制密码表。 在这个5*5的密码表中,共有5行5列字母。 第一列(或第一行)是密钥,其余按照字母顺序。 密钥是一个单词或词组,若有重复字母,可将后面重复的字母去掉。 当然也要把使用频率最少的字母去掉。 第二步整理明文。 将明文每两个字母组成一对。 如果成对后有两个相同字母紧挨或最后一个字母是单个的,就插入一个字母X。 对明文加密规则如下: 1若p1p2在同一行,对应密文c1c2分别是紧靠p1p2右端的字母。 其中第一列被看做是最后一列的右方。 如,按照前表,ct对应oc 2若p1p2在同一列,对应密文c1c2分别是紧靠p1p2下方的字母。 其中第一行被看做是最后一行的下方。 3若p1p2不在同一行,不在同一列,则c1c2是由p1p2确定的矩形的其他两角的字母(至于横向替换还是纵向替换要事先约好,或自行尝试)。 如,按照前表,wh对应tk或kt。 对密文解密规则如下: 1若c1c2在同一行,对应明文p1p2分别是紧靠c1c2左端的字母。 其中最后一列被看做是第一列的左方。 2若c1c2在同一列,对应明文p1p2分别是紧靠c1c2上方的字母。 其中最后一行被看做是第一行的上方。 3若c1c2不在同一行,不在同一列,则p1p2是由c1c2确定的矩形的其他两角的字母。 其实就是反其道而行之。 如密钥crazydog,可编制成 C O H M T R G I N U A B J P V Y E K Q W D F L S X #include #include #include #defineNUM1000 intmain() { inti,j,k=0,m,n,temp=0,length; charkey[NUM],voa[26]; chartable[5][5]; charword[NUM]; printf("欢迎使用playfair加密! "); printf("密钥: "); scanf("%s",key); length=strlen(key); for(i=0;i { if(key[i]=='j') key[i]='i'; } for(i=0;i { for(j=i+1;j if(key[i]==key[j]) { for(intt=j;t { key[t]=key[t+1]; } j--; length--; } if(j==1) { key[j]=0; break; } } for(i=0;i<26;i++) { voa[i]=65+i; } for(i=0;i { key[i]=key[i]-32; } charp; intcount=0; for(i=0;i<26;i++) { p=voa[i]; for(j=0;j { if(p==key[j]) { key[i+length]=p; count+=1; break; } } if(j==length) { key[i+length-count]=p; } } intu=0; for(i=0;i<26;i++) { if(key[i]=='J') { for(u=i;u<26;u++) { key[u]=key[u+1]; } } if(key[i]=='I') key[i]='*'; } temp=0; for(i=0;i<5;i++) { for(j=0;j<5;j++) { table[i][j]=key[j+temp]; printf("%c",table[i][j]); if(j==4) { temp+=5; printf("\n"); } } } printf("明文: "); scanf("%s",word); length=strlen(word); intcounter=0; for(i=0;i { if(word[i]==word[i+1]) { i+=1; counter+=1; } else i+=2; } for(i=0;i { if(word[i]==word[i+1]) { for(j=length+counter-1;j>i+1;j--) { word[j]=word[j-1]; } word[i+1]='x'; } } length=length+counter; if(length%2! =0) { word[length]='x'; length+=1; } for(k=0;k { word[k]=word[k]-32; } for(i=0;i { if(word[i]=='I'||word[i]=='J') { word[i]='*'; } } count=0,k=0; loop: for(i=0;i<5,k { for(j=0;j<5;j++) { for(m=0;m<5;m++) { for(n=0;n<5;n++) { if((table[i][j]==word[k])&&(table[m][n]==word[k+1])&&(i==m)) { count=1; word[k]=table[i][j+1]; word[k+1]=table[m][n+1]; if(j==4) { word[k]=table[i][0]; } if(n==4) { word[k+1]=table[m][0]; } k+=2; if(count==1) { gotoloop; } } elseif((table[i][j]==word[k])&&(table[m][n]==word[k+1])&&(j==n)) { count=1; word[k]=table[i+1][j]; word[k+1]=table[m+1][n]; if(i==4) { word[k]=table[0][j]; } if(m==4) { word[k+1]=table[0][n]; } k+=2; if(count==1) { gotoloop; } } elseif((table[i][j]==word[k])&&(table[m][n]==word[k+1])&&(i! =m)&&(j! =n)) { count=1; word[k]=table[i][n]; word[k+1]=table[m][j]; k+=2; if(count==1) { gotoloop; } } } } } } printf("密文: "); for(k=0;k { printf("%c",word[k]); } printf("\n"); system("pause"); return0; } 运行结果: 3、Vernam(弗纳姆)加解密 主要步骤 1.按递增顺序把每个明文字母作为一个数字,A=0,B=1等等. 2.对输入密文中每一个字母做相同的处理. 3.将明文中的每个字母与密钥中的相应字母相加. 4.如果得到的和大于26,则从中减去26. 5.将和转化为字母,从而得到密文. 例如明文: HOWAREYOU 714220174241420 + 2.密钥NCBTZQARX 132119251601723 3.初始和201623194220243143 4.大于25则模2620162319162024517 5.密文UQXTQUYFR #include #include #include usingnamespacestd; intmain() { stringplain,ciper,key; intlen;//长度三者一致 voidchange(string&,vector vector vector voidre_change(vector cout<<"欢迎使用Vernam加解密: "< cout<<"====================="< intflag;//操作标记 do { cout<<"请选择操作: 1、加密2、解密3、结束: "< cin>>flag; if(flag==1) { cout<<"请输入明文: "; cin>>plain; cout<<"请输入相同长度的密钥: "; cin>>key; len=plain.size(); vector change(plain,p); change(key,k);//字母->数字 c=encrypt_compute(p,k); re_change(c,ciper);//数字->字母 cout<<"密文是: "< } if(flag==2) { cout<<"请输入密文: "; cin>>ciper; cout<<"请输入相同长度的密钥: "; cin>>key; len=ciper.size(); vector change(ciper,c); change(key,k);//字母->数字 p=discrypt_compute(c,k); plain="";//清空明文原来的值 re_change(p,plain); cout<<"明文是: "< } }while(flag! =3); return0; } voidchange(string&plain,vector { for(unsignedinti=0;i { number.push_back(plain[i]-97);//a为0 } } vector { vector for(unsignedinti=0;i { sum.push_back((m[i]+k[i])%26); } returnsum; } vector { vector inttemp; for(unsignedinti=0;i { temp=c[i]-k[i]; if(temp<0)temp+=26; resum.push_back(temp); } returnresum; } voidre_change(vector { stringtemp;//用于处理insert函数变量传递 for(unsignedinti=0;i { temp=sum[i]+97; c.insert(i,temp);//a为0 } } 运行结果:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 密码学 课程设计
![提示](https://static.bdocx.com/images/bang_tan.gif)