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 相关文章推荐
Python重新引入被覆盖的自带function
Jul 16 Python
在Python中用has_key()方法查找键是否存在的教程
May 21 Python
python 性能优化方法小结
Mar 31 Python
Python创建二维数组实例(关于list的一个小坑)
Nov 07 Python
Python使用zip合并相邻列表项的方法示例
Mar 17 Python
python实现音乐下载的统计
Jun 20 Python
Python List cmp()知识点总结
Feb 18 Python
PyQt5 加载图片和文本文件的实例
Jun 14 Python
Flask框架单例模式实现方法详解
Jul 31 Python
python 实现视频 图像帧提取
Dec 10 Python
Python gevent协程切换实现详解
Sep 14 Python
超详细Python解释器新手安装教程
May 10 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
网页游戏开发入门教程二(游戏模式+系统)
2009/11/02 PHP
php 生成文字png图片的代码
2011/04/17 PHP
php中mkdir函数用法实例分析
2014/11/15 PHP
php实现三级级联下拉框
2016/04/17 PHP
PHP时间戳格式全部汇总 (获取时间、时间戳)
2016/06/13 PHP
javascript 构造函数强制调用经验总结
2012/12/02 Javascript
Ext修改GridPanel数据和字体颜色、css属性等
2014/06/13 Javascript
javascript去除字符串左右两端的空格
2015/02/05 Javascript
理解javascript中DOM事件
2015/12/25 Javascript
javascript如何定义对象数组
2016/06/07 Javascript
js实现碰撞检测特效代码分享
2016/10/16 Javascript
Node.js Sequelize如何实现数据库的读写分离
2016/10/23 Javascript
JavaScript实现QQ聊天消息展示和评论提交功能
2017/05/22 Javascript
ejsExcel模板在Vue.js项目中的实际运用
2018/01/27 Javascript
vue 组件 全局注册和局部注册的实现
2018/02/28 Javascript
详解SPA中前端路由基本原理与实现方式
2018/09/12 Javascript
JS实现给数组对象排序的方法分析
2019/06/24 Javascript
Python 文件重命名工具代码
2009/07/26 Python
Python命令行参数解析模块optparse使用实例
2015/04/13 Python
Python yield 使用浅析
2015/05/28 Python
详解python 拆包可迭代数据如tuple, list
2017/12/29 Python
python版微信跳一跳游戏辅助
2018/01/11 Python
Python中使用Counter进行字典创建以及key数量统计的方法
2018/07/06 Python
django_orm查询性能优化方法
2018/08/20 Python
wtfPython—Python中一组有趣微妙的代码【收藏】
2018/08/31 Python
如何在django里上传csv文件并进行入库处理的方法
2019/01/02 Python
Python 使用 attrs 和 cattrs 实现面向对象编程的实践
2019/06/12 Python
python3 tkinter实现点击一个按钮跳出另一个窗口的方法
2019/06/13 Python
python调用动态链接库的基本过程详解
2019/06/19 Python
html5构建触屏网站之网站尺寸探讨
2013/01/07 HTML / CSS
美体小铺奥地利官方网站:The Body Shop奥地利
2019/04/11 全球购物
义和团口号
2014/06/17 职场文书
四风批评与自我批评发言稿
2014/10/14 职场文书
互联网的下一个风口:新的独角兽将诞生
2019/08/02 职场文书
Nginx速查手册及常见问题
2022/04/07 Servers
js基于div丝滑实现贝塞尔曲线
2022/09/23 Javascript