本文实例为大家分享了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