侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

python实现维吉尼亚算法

Python  /  管理员 发布于 7年前   279

本文实例为大家分享了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 ciphertextif __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 plaintextif __name__=="__main__": ciphertext = "RIJVS, AMBPB!" key = "key" text = VigenereDecrypto(ciphertext, key) print(text)import VigenereDecryptoimport VigenereEncryptodef 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个英文字母出现频率表                                                                 重合指数公式

(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 C z),查看字母频率分布统计概率(记pi),计算子密文段长度为n,使用公式:

计算出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编译pyc工程--导包问题解决
    下一条:
    python多线程抽象编程模型详解
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客