python实现维吉尼亚算法


Posted in Python onMarch 20, 2019

本文实例为大家分享了python实现维吉尼亚算法的具体代码,供大家参考,具体内容如下

1 Virginia加密算法、解密算法

Vigenenre密码是最著名的多表代换密码,是法国著名密码学家Vigenenre发明的。Vigenenre密码使用一个词组作为密钥,密钥中每一个字母用来确定一个代换表,每一个密钥字母被用来加密一个明文字母,第一个密钥字母加密第一个明文字母,第二个密钥字母加密第二个明文字母,等所有密钥字母使用完后,密钥再次循环使用,于是加解密前需先将明密文按照密钥长度进行分组。

密码算法可表示如下:。

设明文串为:

M=m1m2…mn,mi∈charset, n是明文长度

秘钥为:

K=k1k2…kd,ki∈charset, d是秘钥长度

密文为:

C=c1c2…cn,ci∈charset, n是密文长度

加密算法:

cj+td=(mj+td+kj ) mod 26

j=1…d,  t=0…ceiling(n/d)-1

其中ceiling(x)函数表示不小于x最小整数

解密算法:

mj+td=(cj+td -kj ) mod 26

j=1…d, t=0…ceiling(n/d)-1

其中ceiling(x)函数表示不小于x最小整数

加解密代码如下

def VigenereEncrypto(message, key):
 msLen = len(message)
 keyLen = len(key)
 message = message.upper()
 key = key.upper()
 raw = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"# 明文空间
 # 定义加密后的字符串
 ciphertext = ""
 # 开始加密
 for i in range(0, msLen):
  # 轮询key的字符
  j = i % keyLen
  # 判断字符是否为英文字符,不是则直接向后面追加且继续
  if message[i] not in raw:
   ciphertext += message[i]
   continue
  encodechr = chr((ord(message[i]) - ord("A") + ord(key[j]) - ord("A")) % 26 + ord("A"))
  # 追加字符
  ciphertext += encodechr
 # 返回加密后的字符串
 return ciphertext
if __name__ == "__main__":
 message = "Hello, World!"
 key = "key"
 text = VigenereEncrypto(message, key)
 print(text)
def VigenereDecrypto(ciphertext, key):
 msLen = len(ciphertext)
 keyLen = len(key)
 key = key.upper()
 raw = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"# 密文空间
 plaintext = ""
 for i in range(0, msLen):# 开始解密
  # 轮询key的字符
  j = i % keyLen
  # 判断字符是否为英文字符,不是则直接向后面追加且继续
  if ciphertext[i] not in raw:
   plaintext += ciphertext[i]
   continue
  decodechr = chr((ord(ciphertext[i]) - ord("A") - ord(key[j]) - ord("A")) % 26 + ord("A"))
  # 追加字符
  plaintext += decodechr
 # 返回加密后的字符串
 return plaintext
if __name__=="__main__":
 ciphertext = "RIJVS, AMBPB!"
 key = "key"
 text = VigenereDecrypto(ciphertext, key)
 print(text)
import VigenereDecrypto
import VigenereEncrypto
def main():
 info = '''==========********=========='''# 开始加密
 print(info, "\n------维吉尼亚加密算法------")
 print(info)
 # 读取测试文本文档
 message = open("test.txt","r+").read()
 print("读取测试文本文档:test.txt")
 print("开始加密!")
 # 输入key
 key = input("请输入密钥:")
 # 进入加密算法
 CipherText = VigenereEncrypto.VigenereEncrypto(message, key)
 # 写入密文文本文档
 C = open("CipherText.txt", "w+")
 C.write(CipherText)
 C.close()
 print("加密后得到的密文是: \n" + CipherText)
 # 开始解密
 print(info, "\n------维吉尼亚解密算法------")
 print(info)
 # 读取加密文本文档
 print("读取密文文本文档:CipherText.txt")
 Ciphertext = open("CipherText.txt", "r+").read()
 # 进入解密算法
 print("开始解密!")
 Plaintext = VigenereDecrypto.VigenereDecrypto(Ciphertext, key)
 P = open("PlainText.txt", "w+")
 # 写入解密文本文档
 P.write(Plaintext)
 P.close()
 print("解密后得到的明文是 : \n" + Plaintext)
if __name__=="__main__":
 main()

2重合指数法

2.1重合指数

设x=X1X2...Xn是一个含有n个字符的字符串,x的重合指数记为Ic(x),定义为x中两个随机元素相同的概率。

设y是一个长度为n密文,即y=y1y2...ym,其中y是密文字母,同样来求从中抽到两个相同字母的概率是多少。为此,设NA为字母A在这份密文中的频数,设Nb为字母B在这份密文中的频数,依此类推

从n个密文字母中抽取两个字母的方式有?_?^2=n(n-1)/2,而其中NA个A组成一对A的方式有CNA2= NA(NA-1)/2,于是从y中抽到两个字母都为A的概率为[NA(NA -1)]/[n(n-1)],..因此,从y中抽到两个相同字母的概率为  (∑▒〖??(??−1)〗)/(?(?−1))

这个数据称为这份密文的重合指数,记为IC(Y)

2.2重合指数法原理

26个英文字母出现频率表                                                                 重合指数公式

python实现维吉尼亚算法

(1)根据频率表,我们可以计算出英语文本的重合指数为0.065。

(2)利用重合指数推测密钥长度的原理在于,对于一个由凯撒密码加密的序列,由于所有字母的位移程度相同,所以密文的重合指数应等于原文语言的重合指数。

(3)假设y=y1 y2...yn是由  Vigenere 密码得到的长度为n的密文。将y按列排成一个m*(n/ m)的矩形阵列,各行分别记为y1,y2...ym.如果m确实是密钥字的长度,则yi中的各个密文字母都是由同一个密钥的移位加密方式得到的。矩阵的每一行对应于子串yi,1≤i≤m。

(4)另一方面,如果m不是密钥字的长度,则 yi中的各个密文字母将是由不同密钥以移位加密方式得到的, yi 中的各个密文字母看起来更随机一些。对于一个随机的英文字母串,其重合指数为0.038。

(5)因为0.065和0.038相差较远,所以我们一般能够确定密钥字的长度,或者说我们能够确定由 Kasiski 测试法得到的密钥字的长度的正确性。

3拟重合指数测试法

拟重合指数测试法:首先子密文段重各个字母的频率进行统计(记为fi, i∈a ? z),查看字母频率分布统计概率(记pi),计算子密文段长度为n,使用公式:

python实现维吉尼亚算法

计算出M0,然后对子密文段移位25次,同样按照上述方法求出M1 — M25的值

根据重合指数的定义知:一个有意义的英文文本,M ≈0.065,所以利用这个规律,就可以确定秘钥中的每一个字母

代码实现

def main():
 fo=open("cipher.txt","r")
 s=fo.read()
 s=str(s)
 fo.close()
 ic=0
 max_num=len(s)//26
 # while ic<0.06:
 #def fenzu():
 #分组
 aves=[0]*max_num
 for i in range(1,max_num):
  count = 0
  zicuan=[]
  for t in range (i):
   fz=s[t:len(s):i]
   zicuan+=[fz]
   count+=1
   #print(count,'韩庚韩庚韩庚',zicuan)
  for js in range (i):
   zicuan[js]=zicuan[js].upper()
  ics=[0]*count
  #统计每个分组的IC值
  for r in range(count):
   ics[r]=tongjicisu(zicuan[r])
  ave =sum(ics)/count
  print('第{}次分片的IC值是{}'.format(i,ave))
  aves[i-1]=ave
 #找到最可能的密钥分组
 key_index=1
 max = 1
 for i in range(max_num):
  max1=abs(aves[i]-0.065)
  if max1<max:
   max=max1
   key_index=i+1
 print('key_length',key_index)
 key = [None]*key_index
 #得到密钥长度后从新按密钥长度分片计算
 zicuan2 = []
 for t in range(key_index):
  fz = s[t:len(s):key_index]
  zicuan2 += [fz]
 for i in range(key_index):
  key[i]=decode(zicuan2[i])
 print(key)
 di = {}.fromkeys(key)
 key=di.keys()
 keys=""
 for i in key:
  keys+=i
 
 print(keys,"密钥")
 mc = VigenereDecrypto(s,keys)
 print(mc,'ecewew')
 
# 统计次数IC值
def tongjicisu(s):
 tongjicisu = [0] * 26
 zff = ""
 ic=-0
 for t in s:
  if 65 <= ord(t) <= 90:
   zff += t
 for cisu in zff:
  tongjicisu[ord(cisu) - 65] += 1
 for i in range (len(tongjicisu)):
  xic=tongjicisu[i]*(tongjicisu[i]-1)/len(zff)/(len(zff)-1)
  ic+=xic
 return ic
 
def decode(s):
 nicos=[0]*26
 for i in range(26):
  nicos[i]=tongjinichonghe(i,s)
 list1=sorted(nicos)
 num = nicos.index(list1[-1])
 ch = chr(num+65)
 #print(ch)
 return ch
#计算拟重合指数
def tongjinichonghe(key,s):
 sniic=0
 p = [0.08167, 0.01492, 0.02782, 0.04253, 0.12702, 0.02228, 0.02015, 0.06094, 0.06966, 0.00153, 0.00772, 0.04025,
   0.02406, 0.06749, 0.07507, 0.01929, 0.00095, 0.05987, 0.06327, 0.09056, 0.02758, 0.00978, 0.02360, 0.00150,
   0.01974, 0.00074]
 tongjinichonghe = [0] * 26
 zff = ""
 #ic=-0
 #转换为只有大写字母的字符串
 for t in s:
  if 65 <= ord(t) <= 90:
   zff += t
 #统计每个字母出现的次数
 for cisu in zff:
  tongjinichonghe[ord(cisu) - 65] += 1
 #求出每个凯撒加密的解密,根据拟重合指数找到正确的密钥
 list0=tongjinichonghe
 list1=[0]*26
 for i in range (26):
  list1[i]=list0[(i+key)%26]
 tongjinichonghe=list1
 for i in range (len(tongjinichonghe)):
  niic=tongjinichonghe[i]/len(tongjinichonghe)*p[i]
  sniic+=niic
 return sniic
 
def VigenereDecrypto(ciphertext, key):
 msLen = len(ciphertext)
 keyLen = len(key)
 key = key.upper()
 raw = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"# 密文空间
 plaintext = ""
 for i in range(0, msLen):# 开始解密
  # 轮询key的字符
  j = i % keyLen
  # 判断字符是否为英文字符,不是则直接向后面追加且继续
  if ciphertext[i] not in raw:
   plaintext += ciphertext[i]
   continue
  decodechr = chr((ord(ciphertext[i]) - ord("A") - ord(key[j]) - ord("A")) % 26 + ord("A"))
  # 追加字符
  plaintext += decodechr
 # 返回加密后的字符串
 return plaintext
 
if __name__ == '__main__':
 main()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
在Django框架中伪造捕捉到的URLconf值的方法
Jul 18 Python
Python封装原理与实现方法详解
Aug 28 Python
深入理解Python中的 __new__ 和 __init__及区别介绍
Sep 17 Python
python实现感知机线性分类模型示例代码
Jun 02 Python
python实现数据分析与建模
Jul 11 Python
django创建最简单HTML页面跳转方法
Aug 16 Python
Python连接SQLite数据库并进行增册改查操作方法详解
Feb 18 Python
keras训练浅层卷积网络并保存和加载模型实例
Jul 02 Python
详解Python多线程下的list
Jul 03 Python
什么是Python包的循环导入
Sep 08 Python
Python绘制组合图的示例
Sep 18 Python
python实现计算图形面积
Feb 22 Python
python多线程抽象编程模型详解
Mar 20 #Python
基于python生成器封装的协程类
Mar 20 #Python
python实现栅栏加解密 支持密钥加密
Mar 20 #Python
python实现Virginia无密钥解密
Mar 20 #Python
python实现维吉尼亚加密法
Mar 20 #Python
Python multiprocess pool模块报错pickling error问题解决方法分析
Mar 20 #Python
python实现对输入的密文加密
Mar 20 #Python
You might like
PHP连接SQLServer2005的实现方法(附ntwdblib.dll下载)
2012/07/02 PHP
七款最流行的PHP本地服务器分享
2013/02/19 PHP
PHP与javascript实现变量交互的示例代码
2013/07/23 PHP
ThinkPHP中U方法的使用浅析
2014/06/13 PHP
PHP实现的sqlite数据库连接类
2014/12/12 PHP
php实现多城市切换特效
2015/08/09 PHP
非常重要的php正则表达式详解
2016/01/04 PHP
php使用ftp远程上传文件类(完美解决主从文件同步问题的方法)
2016/09/23 PHP
JavaScript的Cookies
2008/01/16 Javascript
JavaScript 基于原型的对象(创建、调用)
2009/10/16 Javascript
jQuery当鼠标悬停时放大图片的效果实例
2013/07/03 Javascript
js字符串完全替换函数分享
2014/12/03 Javascript
js实现从中间开始往上下展开网页窗口的方法
2015/03/02 Javascript
js实现非常简单的焦点图切换特效实例
2015/05/07 Javascript
JavaScript数组各种常见用法实例分析
2015/08/04 Javascript
详解JS几种变量交换方式以及性能分析对比
2016/11/25 Javascript
老生常谈的跨域处理
2017/01/11 Javascript
Angular.JS去掉访问路径URL中的#号详解
2017/03/30 Javascript
JS实现动态添加DOM节点和事件的方法示例
2017/04/28 Javascript
layer弹出的iframe层在执行完毕后关闭当前弹出层的方法
2018/08/17 Javascript
24行JavaScript代码实现Redux的方法实例
2019/11/17 Javascript
使用webpack/gulp构建TypeScript项目的方法示例
2019/12/18 Javascript
jquery实现轮播图特效
2020/04/12 jQuery
npm全局环境变量配置详解
2020/12/15 Javascript
python条件和循环的使用方法
2013/11/01 Python
python的unittest测试类代码实例
2017/12/07 Python
Python+Pandas 获取数据库并加入DataFrame的实例
2018/07/25 Python
使用python实现语音文件的特征提取方法
2019/01/09 Python
CSS3 选择器 属性选择器介绍
2012/01/21 HTML / CSS
德国鞋子网上商店:Omoda.de
2017/03/31 全球购物
汇集了世界上最好的天然和有机美容产品:LoveLula
2018/02/05 全球购物
怎样有效的进行自我评价
2013/10/06 职场文书
食堂厨师岗位职责
2014/08/25 职场文书
个人总结格式范文
2015/03/09 职场文书
2019个人工作总结
2019/06/21 职场文书
送给自己的励志语句:要安静的优秀,悄无声息的坚强
2019/11/26 职场文书