实验一 实现一个多表古典加密和解密程序

简介:

一、实验内容

掌握多表古典加密方法,能用高级语言实现古典加密方法。多表古典加密方法主要有Playfair(替换)体制、Vigenere(维热纳尔密码-维热纳尔)体制、Beaufor()体制、Vernam体制和Hill体制,用高级语言实现所有体制的加密和解密算法。

二、多表古典加密算法的基本原理及其算法流程

   根据密码算法加解密时使用替换表多少的不同,替代密码又可分为单表替代密码和多表替代密码。

  单表替代密码的密码算法加解密时使用一个固定的替换表。单表替代密码又可分为一般单表替代密码、移位密码、仿射密码、密钥短语密码。

  多表替代密码的密码算法加解密时使用多个替换表。 多表替代密码有弗吉尼亚密码、希尔(Hill)密码、一次一密钥密码、Playfair密码。

单表替代密码单表替代密码对明文中的所有字母都使用一个固定的映射(明文字母表到密文字母表)。设A={a0, a1,…, an-1}为包含了n个字母的明文字母表;

  B={b0, b1,…, bn-1} 为包含n个字母的密文字母表,单表替代密码使用了A到B的映射关系:f:A→B, f ( ai )= bj

  一般情况下,f 是一一映射,以保证加密的可逆性。加密变换过程就是将明文中的每一个字母替换为密文字母表的一个字母。而单表替代密码的密钥就是映射f或密文字母表。经常密文字母表与明文字母表的字符集是相同的,这时的密钥就是映射f。下面给出几种典型的单表替代密码。

  ⒈一般单表替代密码

  一般单表替代密码的原理是以26个英文字母集合上的一个置换π为密钥,对明文消息中的每个字母依次进行变换。可描述为:明文空间M和密文空间C都是26个英文字母的集合,密钥空间K={π:Z26→Z26|π是置换},是所有可能置换的集合。

  对任意π∈K,定义:

  加密变换:eπ(m)=π(m)=c

  解密变换:dπ(c) = π-1(c)=m, π-1是π的逆置换。

  例:设置换π的对应关系如下:

  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

  q w e r t y u i o p a s d f g h j k l z x c v b n m

  试用单表替代密码以π为密钥对明文消息message加密,然后写出逆置换 ,并对密文解密。

  解:以π为密钥用单表替代密码对明文消息message加密,所得

  密文消息为: π(m) π(e) π(s) π(s) π(a) π(g) π(e)=dtllqut

  一般单表替代密码算法特点:

  ▲密钥空间K很大,|K|=26!=4×1026 ,破译者穷举搜索计算不可行,1微秒试一个密钥,遍历全部密钥需要1013年。

  ▲移位密码体制是替换密码体制的一个特例,它仅含26个置换做为密钥空间。

  密钥π不便记忆。

  ▲针对一般替换密码密钥π不便记忆的问题,又衍生出了各种形式单表替代密码。

  ⒉移位密码

  明文空间M、密文空间C都是和密钥空间K满足,即把26个英文字母与整数0,1,2,…,25一一对应。

  加密变换,E={E:Z26→Z26, Ek (m) = m + k (mod26)| m∈M, k∈K }

  解密变换,D={D:Z26→Z26, Dk (c) = c-k (mod26)| c∈C, k∈K }

  解密后再把Z26中的元素转换英文字母。

  显然,移位密码是前面一般单表替代密码的一个特例。当移位密码的 密钥k=3时,就是历史上著名的凯撒密码(Caesar)。根据其加密函数特 点,移位密码也称为加法密码。

  ⒊仿射密码

  仿射密码也是一般单表替代密码的一个特例,是一种线性变换。仿射密码的明文空间和密文空间与移位密码相同,但密钥空间为 K={(k1,k2)| k1,k2∈Z26,gcd(k1,26)=1}

  对任意m∈M,c∈C,k = (k1,k2)∈K,定义加密变换为 c = Ek (m) = k1 m +k2 (mod 26)

  相应解密变换为: m = Dk (c) = k1 (c-k2) (mod 26)

  其中,K1 k1=1mod26 。很明显,k1=1时即为移位密码,而k2=1则称为乘法密码。

  ⒋密钥短语密码

  选用一个英文短语或单词串作为密钥,去掉其中重复的字母得到一个无重复字母的字符串,然后再将字母表中的其它字母依次写于此字母串后,就可构造出一个字母替代表。当选择上面的密钥进行加密时,若明文为“china”,则密文为“yfgmk”。显然,不同的密钥可以得到不同的替换表,对于明文为英文单词或短语的情况时,密钥短语密码最多可能有26!=4×1026个不同的替换表。

多表替代密码

  单表替代密码表现出明文中单字母出现的频率分布与密文中相同, 多表替代密码使用从明文字母到密文字母的多个映射来隐藏单字母出现 的频率分布,每个映射是简单替代密码中的一对一映射多表替代密码将 明文字母划分为长度相同的消息单元,称为明文分组,对明文成组地进 行替代,同一个字母有不同的密文,改变了单表替代密码中密文的唯一 性,使密码分析更加困难。

  多表替代密码的特点是使用了两个或两个以上的替代表。著名的维吉尼亚密码和Hill密码等均是多表替代密码。

  ⒈维吉尼亚密码

  维吉尼亚密码是最古老而且最著名的多表替代密码体制之一,与位移密码体制相似,但维吉尼亚密码的密钥是动态周期变化的。

  该密码体制有一个参数n。在加解密时,同样把英文字母映射为0-25的数字再进行运算,并按n个字母一组进行变换。明文空间、密文空间及密钥空间都是长度为n的英文字母串的集合,因此可表示

  加密变换定义如下:

  设密钥 k=(k1,k2,…,kn), 明文m=(m1,m2,…,mn), 加密变换为:

  Ek(m)=(c1,c2,…,cn),

  其中ci(mi + ki)(mod26),i =1,2,…,n

  对密文 c=(c1,c2,…,cn), 解密变换为:

  Dk(c)=(m1,m2,…,mn), 其中 mi=(ci -ki)(mod26),i =1,2,…,n

 

三、设计要求:

编程实现移位密码、仿射密码、维吉尼亚密码和置换密码,要求如下:

1、程序输入为明文和密钥(对于仿射密码应该检查密钥的合法性);

2、执行加密和解密过程;

3、输出加密的密文和解密恢复的明文,并和开始输入的明文进行比较。

四、设计步骤:

程序在JAVA环境中实现,由于编程基础不够扎实可能程序没有明显的体现出面向对象的风格,期望老师见谅。

先设计一个图形界面。

 

 

 

在同一个类中加入各个算法即可。

详细情况可以参考源代码

1.5实验小结

 本次实验难度不大,只是要对各个算法有一个比较深刻的认识即可。

  在实验中,为了兼顾图形界面,我编写了较长时间。

 

部分源代码:

 

 


 
 
  1. public void ywjiami(){                        
  2.         String s1; 
  3.         String s2; 
  4.         String es=""; 
  5.         char zifu[]; 
  6.         s1=t1.getText();//输入明文 
  7.         s2=t4.getText();//输入密钥 
  8.         int key; 
  9.         key=Integer.parseInt(s2); 
  10.         zifu = s1.toCharArray(); 
  11.          /*for (int i = 0;i<zifu.length ;i++ ) 
  12.          {   
  13.              zifu[i]=(char)(((zifu[i]-97+a)%26)+97); 
  14.              
  15.          }*/ 
  16.         for(int i=0;i<zifu.length;i++) {   
  17.             char c=zifu[i];//=zifu.charAt(i);  
  18.             if(c>='a' && c<='z') //  是小写字母  
  19.              {  
  20.                  c+=key%26;  //移动key%26 位  
  21.                   if(c<'a') c+=26;  // 向左超界  
  22.                   if(c>'z') c-=26;  // 向右超界  
  23.               }  
  24.              else if(c>='A' && c<='Z') //  是大写字母  
  25.             {   
  26.                 c+=key%26;  
  27.                 if(c<'A') c+=26;  
  28.                 if(c>'Z') c-=26;  
  29.              }  
  30.                    es+=c;  
  31.                } 
  32.         String s3=new String(es); 
  33.         s3s3=s3.toUpperCase(); 
  34.         t2.setText(s3); 
  35. } 
  36.      
  37. /*移位解密算法*/ 
  38.     public void ywjiemi(){                         
  39.         String s1; 
  40.         String s2,es=""; 
  41.         char zifu[]; 
  42.         s1=t2.getText(); 
  43.         s2=t4.getText(); 
  44.         int bb,key; 
  45.         bb=Integer.parseInt(s2); 
  46.         key=-bb; 
  47.         zifu = s1.toCharArray(); 
  48.          /*for (int i = 0;i<zifu.length ;i++ ) 
  49.          {   
  50.              zifu[i]=(char)(((zifu[i]-97-a)%26)+97); 
  51.              
  52.          }*/ 
  53.          for(int i=0;i<zifu.length;i++) {   
  54.             char c=zifu[i];//=zifu.charAt(i);  
  55.             if(c>='a' && c<='z') //  是小写字母  
  56.              {  
  57.                  c+=key%26;  //移动key%26 位  
  58.                   if(c<'a') c+=26;  // 向左超界  
  59.                   if(c>'z') c-=26;  // 向右超界  
  60.               }  
  61.              else if(c>='A' && c<='Z') //  是大写字母  
  62.             {   
  63.                 c+=key%26;  
  64.                 if(c<'A') c+=26;  
  65.                 if(c>'Z') c-=26;  
  66.              }  
  67.                    es+=c;  
  68.                } 
  69.         String s3=new String(es); 
  70.         s3s3=s3.toLowerCase(); 
  71.         t3.setText(s3); 
  72. } 
  73.   
  74. /*求最大公约数-辗转相除法*/ 
  75. int gcd(int a, int b)                              
  76. { 
  77.     int k = 0; 
  78.   
  79.     do 
  80.     { 
  81.         k = a%b; 
  82.         a = b; 
  83.         b = k; 
  84.     }while(k!=0); 
  85.     return a; 
  86. } 
  87.   
  88. /*求模逆*/ 
  89. int Ni(int a, int b)                              
  90. { 
  91.     int i = 0; 
  92.     while(a*(++i)%b!=1); 
  93.     return i; 
  94. } 
  95. /*仿射加密算法*/ 
  96. public void fcjiami(){                           
  97.     int  i=0, a=0, b=0, tmp; 
  98.     String s1; 
  99.     String s2; 
  100.     char zifu[]; 
  101.     s1=t1.getText(); 
  102.     s2=t4.getText(); 
  103.     a=Integer.parseInt(s2)/10; 
  104.     b=Integer.parseInt(s2)%10; 
  105.     zifu = s1.toCharArray(); 
  106. /*如果输入密钥不合法则显示密钥错误*/ 
  107. if(gcd(a,26)!=1)                                
  108.     { 
  109.         String s3=new String(); 
  110.             s3="密钥错误"; 
  111.             t3.setText(s3);//密钥 
  112.     } 
  113.   
  114.     for(i=0; i<zifu.length; i++) 
  115.     { 
  116.         if(zifu[i]>96&&zifu[i]<123) 
  117.         zifu[i] = (char)((a*(zifu[i]-97)+b)%26+65); 
  118.         else if(zifu[i]>64&&zifu[i]<91) 
  119.         zifu[i] = (char)((a*(zifu[i]-65)+b)%26+65); 
  120.     } 
  121.     String s4=new String(zifu); 
  122.     t2.setText(s4); 
  123. } 
  124. /*仿射解密算法*/ 
  125. public void fcjiemi(){                          
  126.     int  i=0, a=0, b=0, tmp; 
  127.     String s1; 
  128.     String s2; 
  129.     char zifu[]; 
  130.     s1=t1.getText(); 
  131.     s2=t4.getText(); 
  132. /*在密钥输入文本框中输入2位密钥首先转换成2位整数在利用‘/’和‘%’算法求出2个合法密钥在进行计算*/ 
  133.     a=Integer.parseInt(s2)/10; 
  134.     b=Integer.parseInt(s2)%10; 
  135.     zifu = s1.toCharArray(); 
  136.   
  137.     for(i=0; i<zifu.length; i++){ 
  138.         if(zifu[i]>64&&zifu[i]<91) 
  139.         { 
  140.         tmp = Ni(a,26)*((zifu[i]-65)-b); 
  141.         if(tmp<0) 
  142.             zifu[i] = (char)(tmp%26+26+97); 
  143.         else 
  144.             zifu[i] = (char)(tmp%26+97); 
  145.         } 
  146.     } 
  147.          String s4=new String(zifu); 
  148.          t3.setText(s4); 
  149.      
  150. } 
  151.   
  152. /*维吉尼亚加密算法*/ 
  153. public void wjnyjiami()     
  154. { 
  155.     int i,j,s=0; 
  156.     int k=0 ; 
  157.     String s1; 
  158.     String s2; 
  159.     char zifu[],miyao[]; 
  160.     s1=t1.getText();//输入明文 
  161.     s2=t4.getText();//输入密钥 
  162.     miyao =s2.toCharArray(); 
  163.     zifu = s1.toCharArray(); 
  164.      
  165.     for(i=0; i<zifu.length; i++){ 
  166.         zifu[i] = (char)((zifu[i]-97+(miyao[k%miyao.length]-97))%26+97); 
  167.         k++; 
  168.     } 
  169.     String s3=new String(zifu); 
  170.     s3s3=s3.toUpperCase(); 
  171.     t2.setText(s3); 
  172. } 
  173. /*维吉尼亚解密算法*/ 
  174. public void wjnyjiemi()     
  175. { 
  176.     int i,j,k=0,tmp; 
  177.     String s1; 
  178.     String s2; 
  179.     char zifu[],miyao[]; 
  180.     s1=t2.getText();//密文 
  181.     s2=t4.getText();//密钥 
  182.     s1s1=s1.toLowerCase(); 
  183.     miyao =s2.toCharArray(); 
  184.     zifu = s1.toCharArray(); 
  185. /*解密算法中会出现减出负数的状况如果出现负数加26解决问题*/ 
  186.     for (i =0;i<zifu.length ;i++ ){    
  187.          tmp = (zifu[i]-miyao[k%(miyao.length)]);  
  188.          zifu[i]=(char)(tmp+65); 
  189.          if (tmp<0) 
  190.          zifu[i] =(char)(tmp+65+26); 
  191.         k++; 
  192.       }; 
  193.     String s3=new String(zifu); 
  194.     s3s3=s3.toLowerCase(); 
  195.     t3.setText(s3); 
  196. } 

 

注:*********由于源代码过大,我就上传到下载中心了,可复制下面连接去下载********

http://down.51cto.com/data/417584

 




本文转自 梦朝思夕 51CTO博客,原文链接:http://blog.51cto.com/qiangmzsx/873131

相关文章
|
存储 测试技术 数据安全/隐私保护
【Docker项目实战】使用Docker部署DailyTxT加密日记网络应用程序
【4月更文挑战第6天】使用Docker部署DailyTxT加密日记网络应用程序
507 2
|
开发框架 网络协议 前端开发
一个对C#程序混淆加密,小巧但够用的小工具
一个对C#程序混淆加密,小巧但够用的小工具
472 1
|
Java Maven 数据安全/隐私保护
如何实现Java打包程序的加密代码混淆,避免被反编译?
【10月更文挑战第15天】如何实现Java打包程序的加密代码混淆,避免被反编译?
4763 2
|
网络协议 安全 网络安全
LabVIEW程序的常见加密方式
LabVIEW程序的常见加密方式
1098 1
|
vr&ar 数据安全/隐私保护
实验六 文本串的加密解密
实验六 文本串的加密解密
|
算法 安全 数据安全/隐私保护
实战案例2:简单的文件加密解密程序。
实战案例2:简单的文件加密解密程序。
|
算法 vr&ar 数据安全/隐私保护
$文本串加密和解密程序
$文本串加密和解密程序
|
存储 API 数据库
c# 如何将程序加密隐藏?
c# 如何将程序加密隐藏?
438 0
c# 如何将程序加密隐藏?
|
算法 网络安全 数据安全/隐私保护
网络安全实验六 DES对称加密算法详解
网络安全实验六 DES对称加密算法详解
1560 0
|
算法 程序员 数据安全/隐私保护
【Python】编写代码,实现恺撒密码的加密算法以及欧氏距离程序
在本次python文章种,编写此函数的目的,主要是为了理解和掌握自定义函数过程的定义和调用方法,以及函数中的参数的作用,本次定义的函数是恺撒密码加解密算法