密码学课程设计.doc_第1页
密码学课程设计.doc_第2页
密码学课程设计.doc_第3页
密码学课程设计.doc_第4页
密码学课程设计.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

密码学课程设计多表古典加密和解密程序姓名:林良松 专业:信息工程班级:1132101学号:201130210116 2014-1-11一、 实验目的:掌握多表古典加密方法。二、 实验要求:能用高级语言实现古典加密方法。三、 实验内容:多表古典加密方法主要有Playfair体制、Vigenere体制、Beaufor体制、Vernam体制和Hill体制,用高级语言实现其中一种体制的加密和解密算法。四、实验过程:1、Vigenere加密解密:维吉尼亚密码引入了“密钥”的概念,即根据密钥来决定用哪一行的密表来进行替换,以此来对抗字频统计。#include #include using namespace std;const int N=26;char vNN=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;int number(char x)/把行号字母对应到数字 char y=a; for(int i=0;iN;i+) if(x=(y+i) return i; void encryption(string m,string k)/加密 coutm; coutk; int mlen,klen; mlen=m.length(); klen=k.length(); char *p,*q,*t;/明文,初始密钥,密钥串。把string换成char p=new charm.length()+1; strcpy(p,m.c_str(); q=new chark.length()+1; strcpy(q,k.c_str(); t=new charm.length()+1; int j=0; for(int i=0;imlen;i+) ti=qj; j+; j=j%klen; /生成密钥 cout密文:; for(i=0;imlen;i+) coutvnumber(ti)number(pi); coutendl;void disencryption(string c,string k)/解密 coutc; coutk; int clen,klen; clen=c.length(); klen=k.length(); char *p,*q,*t;/密文,初始密钥,密钥串。把string换成char p=new charc.length()+1; strcpy(p,c.c_str(); q=new chark.length()+1; strcpy(q,k.c_str(); t=new charc.length()+1; int j=0; for(int i=0;iclen;i+) ti=qj; j+; j=j%klen; /生成密钥 cout明文:; for(i=0;iclen;i+) for(int j=0;jN;j+) if(vnumber(ti)j=pi) coutchar(j+97);break; coutendl;int main() for(int i=1;iN;i+) for(int j=0;jN;j+) vij=vi-1(j+1)%N; /方阵初始化 cout欢迎使用Vigenere加密!endlendl; cout请选择要进行的操作endl; int flag; do cout1.加密2.解密3.结束:flag; string m,k; if(flag=1)encryption(m,k); else if(flag=2) disencryption(m,k); else if(flag!=1&flag!=2&flag!=3) cout输入错误,请重新输入!; while(flag!=3); return 0;运行结果:2、Playfair 加解密算法描述:Playfair密码出现于1854年,它依据一个5*5的正方形组成的密码表来编写,密码表里排列有25个字母。如果一种语言字母超过25个,可以去掉使用频率最少的一个。英语中z使用最少,可以去掉它。法语一般去掉w或k,德语则是把i和j合起来当成一个字母看待。英语中z使用最少,可以去掉它。加密描述:第一步是编制密码表。在这个5*5的密码表中,共有5行5列字母。第一列(或第一行)是密钥,其余按照字母顺序。密钥是一个单词或词组,若有重复字母,可将后面重复的字母去掉。当然也要把使用频率最少的字母去掉。第二步整理明文。将明文每两个字母组成一对。如果成对后有两个相同字母紧挨或最后一个字母是单个的,就插入一个字母X。对明文加密规则如下: 1 若p1 p2在同一行,对应密文c1 c2分别是紧靠p1 p2 右端的字母。其中第一列被看做是最后一列的右方。如,按照前表,ct对应oc 2 若p1 p2在同一列,对应密文c1 c2分别是紧靠p1 p2 下方的字母。其中第一行被看做是最后一行的下方。 3 若p1 p2不在同一行,不在同一列,则c1 c2是由p1 p2确定的矩形的其他两角的字母(至于横向替换还是纵向替换要事先约好,或自行尝试)。如,按照前表,wh对应tk或kt。对密文解密规则如下: 1 若c1 c2在同一行,对应明文p1 p2分别是紧靠c1 c2 左端的字母。其中最后一列被看做是第一列的左方。 2 若c1 c2在同一列,对应明文p1 p2分别是紧靠c1 c2 上方的字母。其中最后一行被看做是第一行的上方。 3 若c1 c2不在同一行,不在同一列,则p1 p2是由c1 c2确定的矩形的其他两角的字母。 其实就是反其道而行之。如密钥crazy dog,可编制成 COHMTRGINUABJPVYEKQWDFLSX#include #include #include #define NUM 1000int main()int i,j,k=0,m,n,temp=0,length;char keyNUM,voa26;char table55;char wordNUM;printf(欢迎使用playfair加密!);printf(密钥: );scanf(%s,key);length=strlen(key); for(i=0;ilength;i+) if(keyi=j) keyi=i; for(i=0;ilength;i+) for(j=i+1;jlength;j+) if(keyi=keyj) for(int t=j;tlength;t+) keyt=keyt+1; j-; length-; if(j=1) keyj=0; break; for(i=0;i26;i+) voai=65+i;for(i=0;ilength;i+) keyi=keyi-32;char p;int count=0;for(i=0;i26;i+) p=voai; for(j=0;jlength;j+) if(p=keyj) keyi+length=p; count+=1; break; if(j=length) keyi+length-count=p; int u=0;for(i=0;i26;i+) if(keyi=J) for(u=i;u26;u+) keyu=keyu+1; if(keyi=I) keyi=*; temp=0;for(i=0;i5;i+) for(j=0;j5;j+) tableij=keyj+temp; printf(%c ,tableij); if(j=4) temp+=5; printf(n); printf(明文: );scanf(%s,word);length=strlen(word);int counter=0;for(i=0;ilength;) if(wordi=wordi+1) i+=1; counter+=1; else i+=2;for(i=0;ii+1;j-) wordj=wordj-1; wordi+1=x; length=length+counter;if(length%2!=0) wordlength=x; length+=1;for(k=0;klength;k+) wordk=wordk-32;for(i=0;ilength;i+) if(wordi=I|wordi=J) wordi=*; count=0,k=0; loop: for(i=0;i5,klength;i+) for(j=0;j5;j+) for(m=0;m5;m+) for(n=0;n5;n+) if(tableij=wordk)&(tablemn=wordk+1)&(i=m) count=1; wordk=tableij+1; wordk+1=tablemn+1; if(j=4) wordk=tablei0; if(n=4) wordk+1=tablem0; k+=2; if(count=1) goto loop; else if(tableij=wordk)&(tablemn=wordk+1)&(j=n) count=1; wordk=tablei+1j; wordk+1=tablem+1n; if(i=4) wordk=table0j; if(m=4) wordk+1=table0n; k+=2; if(count=1) goto loop; else if(tableij=wordk)&(tablemn=wordk+1)&(i!=m)&(j!=n) count=1; wordk=tablein; wordk+1=tablemj; k+=2; if(count=1) goto loop; printf(密文: );for(k=0;klength;k+) printf(%c ,wordk);printf(n); system(pause);return 0;运行结果:3、Vernam(弗纳姆)加解密主要步骤1.按递增顺序把每个明文字母作为一个数字,A=0,B=1等等. 2.对输入密文中每一个字母做相同的处理. 3.将明文中的每个字母与密钥中的相应字母相加. 4.如果得到的和大于26,则从中减去26. 5.将和转化为字母,从而得到密文.例如 明文: H O W A R E Y O U 7 14 22 0 17 4 24 14 20 + 2.密钥 N C B T Z Q A R X 13 2 1 19 25 16 0 17 23 3.初始和 20 16 23 19 42 20 24 31 43 4.大于25则模26 20 16 23 19 16 20 24 5 17 5.密文 U Q X T Q U Y F R#include #include #include using namespace std;int main() string plain,ciper,key; int len; /长度三者一致 void change(string &, vector&);/字符变数字 vector encrypt_compute(vector m,vector k);/加密计算 vector discrypt_compute(vector c,vector k);/解密计算 void re_change( vector&,string &);/数字变字符 cout欢迎使用Vernam加解密:endl; cout=endl; int flag; /操作标记 do cout请选择操作:1、加密 2、解密 3、结束:flag; if(flag=1) coutplain; coutkey; len = plain.size(); vector p,c,k; /存变换的数字 change(plain, p); change(key, k); /字母-数字 c = encrypt_compute(p,k); re_change(c,ciper); /数字-字母 cout密文是:ciperendl; if(flag=2) coutciper; coutkey; len = ciper.size(); vector p,c,k; /存变换的数字 change(ciper, c); change(key, k); /字母-数字 p = discrypt_compute(c,k); plain=;/清空明文原来的值 re_change(p,plain); cout明文是:plainendl; while(flag!=3); return 0;void change(string &plain, vector&number) /字母变数字 for (unsigned int i=0;iplain.size();i+) number.push_back(plaini-97); /a为0 vector encrypt_compute(vector m,vector k) /加密计算 vector sum; for(unsigned int i=0; im.size(); i+) sum.push_back(mi+ki)%26); return sum;vector discrypt_compute(vector c,vector k) /解密计算

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论