本文实例为大家分享了Virginia无密钥解密的具体代码,供大家参考,具体内容如下
加密
virginia加密是一种多表替换加密方法,通过这种方法,可以有效的解决单表替换中无法应对的字母频度攻击。这种加密方法最重要的就是选取合适的密钥,一旦密钥被公开,保密性也就无从谈起。结合virginia加密原理,给出使用python实现的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
plainText = "whenigotthethemeithoughtofgooglesartificialintelligencealphagothisprogramoverthebestofhumanplayeriwanttoaskwhenscienceandtechnologycontinuetodevelopwehumanbeingswillbewhatpositionweshouldrealizethatthedevelopmentofscienceandtechnologyisirreversibleanditconstituteaprimaryprductiveforcebutmanmustkeeppacewiththetimestoenhancetheablitytocontrol" # 密文 alphabet = "abcdefghijklmnopqrstuvwxyz" # 26个字母 cipherText = ""; key = "helloworld" # 密钥 keyLen = len (key) plainTextLen = len (plainText) j = 0 for i in range ( 0 ,plainTextLen): j = i % keyLen keyNum = alphabet.index(key[j]) plainNum = alphabet.index(plainText[i]) plainTemp = alphabet[(keyNum * plainNum) % 26 ] # 密钥对明文作用 cipherText + = plainTemp print (cipherText) |
解密
重点谈谈解密部分。这里的解密主要分为获取密钥长度,根据密钥长度获取密钥,根据密钥获取明文三个部分。
获取密钥长度
使用暴力破解密钥长度的方法,循环遍历可能的密钥长度。每次循环中,记录在这种密钥长度下重复相隔密钥长度密文的次数,从理论上来讲,次数最多的那个密钥长度,最有可能正确。当密文长度足够长时,正确的可能性很高。给出获取密钥长度的python函数代码:
1
2
3
4
5
6
7
8
9
10
11
12
|
def getKeyLen(cipherText): # 获取密钥长度 keylength = 1 maxCount = 0 for step in range ( 3 , 18 ): # 循环密钥长度 count = 0 for i in range (step, len (cipherText) - step): if cipherText[i] = = cipherText[i + step]: count + = 1 if count>maxCount: # 每次保存最大次数的密钥长度 maxCount = count keylength = step return keylength # 返回密钥长度 |
获取密钥
当已经获取密钥长度之后,我们可以通过分组将相同密钥作用下的密文进行分组,在每一组中,都是一个简单的单表替换加密。在这种情况下,我们通过重合指数法破解密钥,给出获取密钥部分的python函数代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
def getKey(text,length): # 获取密钥 key = [] # 定义空白列表用来存密钥 alphaRate = [ 0.08167 , 0.01492 , 0.02782 , 0.04253 , 0.12705 , 0.02228 , 0.02015 , 0.06094 , 0.06996 , 0.00153 , 0.00772 , 0.04025 , 0.02406 , 0.06749 , 0.07507 , 0.01929 , 0.0009 , 0.05987 , 0.06327 , 0.09056 , 0.02758 , 0.00978 , 0.02360 , 0.0015 , 0.01974 , 0.00074 ] matrix = textToList(text,length) for i in range (length): w = [row[i] for row in matrix] #获取每组密文 li = countList(w) powLi = [] #算乘积 for j in range ( 26 ): Sum = 0.0 for k in range ( 26 ): Sum + = alphaRate[k] * li[k] powLi.append( Sum ) li = li[ 1 :] + li[: 1 ] #循环移位 Abs = 100 ch = '' for j in range ( len (powLi)): if abs (powLi[j] - 0.065546 )< Abs : # 找出最接近英文字母重合指数的项 Abs = abs (powLi[j] - 0.065546 ) # 保存最接近的距离,作为下次比较的基准 ch = chr (j + 97 ) key.append(ch) return key |
破解明文
在已知密钥和明文的基础上,我们很容易就可以得到明文,给出python代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
def virginiaCrack(cipherText): # 解密函数 length = getKeyLen(cipherText) #得到密钥长度 key = getKey(cipherText,length) #找到密钥 keyStr = '' for k in key: keyStr + = k print ( 'the Key is:' ,keyStr) plainText = '' index = 0 for ch in cipherText: c = chr (( ord (ch) - ord (key[index % length])) % 26 + 97 ) plainText + = c index + = 1 return plainText # 返回明文 |
代码
这是解密部分的全部代码,注意需要自己添加密文文件的位置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
def virginiaCrack(cipherText): # 解密函数 length = getKeyLen(cipherText) #得到密钥长度 key = getKey(cipherText,length) #找到密钥 keyStr = '' for k in key: keyStr + = k print ( 'the key:' ,keyStr) plainText = '' index = 0 for ch in cipherText: c = chr (( ord (ch) - ord (key[index % length])) % 26 + 97 ) plainText + = c index + = 1 return plainText def openfile(fileName): # 读文件 file = open (fileName, 'r' ) text = file .read() file .close(); text = text.replace( '\n' ,'') return text def getKeyLen(cipherText): # 获取密钥长度 keylength = 1 maxCount = 0 for step in range ( 3 , 18 ): # 循环密钥长度 count = 0 for i in range (step, len (cipherText) - step): if cipherText[i] = = cipherText[i + step]: count + = 1 if count>maxCount: maxCount = count keylength = step return keylength def getKey(text,length): # 获取密钥 key = [] # 定义空白列表用来存密钥 alphaRate = [ 0.08167 , 0.01492 , 0.02782 , 0.04253 , 0.12705 , 0.02228 , 0.02015 , 0.06094 , 0.06996 , 0.00153 , 0.00772 , 0.04025 , 0.02406 , 0.06749 , 0.07507 , 0.01929 , 0.0009 , 0.05987 , 0.06327 , 0.09056 , 0.02758 , 0.00978 , 0.02360 , 0.0015 , 0.01974 , 0.00074 ] matrix = textToList(text,length) for i in range (length): w = [row[i] for row in matrix] #获取每组密文 li = countList(w) powLi = [] #算乘积 for j in range ( 26 ): Sum = 0.0 for k in range ( 26 ): Sum + = alphaRate[k] * li[k] powLi.append( Sum ) li = li[ 1 :] + li[: 1 ] #循环移位 Abs = 100 ch = '' for j in range ( len (powLi)): if abs (powLi[j] - 0.065546 )< Abs : # 找出最接近英文字母重合指数的项 Abs = abs (powLi[j] - 0.065546 ) # 保存最接近的距离,作为下次比较的基准 ch = chr (j + 97 ) key.append(ch) return key def countList(lis): # 统计字母频度 li = [] alphabet = [ chr (i) for i in range ( 97 , 123 )] for c in alphabet: count = 0 for ch in lis: if ch = = c: count + = 1 li.append(count / len (lis)) return li def textToList(text,length): # 根据密钥长度将密文分组 textMatrix = [] row = [] index = 0 for ch in text: row.append(ch) index + = 1 if index % length = = 0 : textMatrix.append(row) row = [] return textMatrix if __name__ = = '__main__' : cipherText = openfile(r'') # 这里要根据文档目录的不同而改变 plainText = virginiaCrack(cipherText) print ( 'the plainText:\n' ,plainText) |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/Aslani/article/details/53729804