您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關如何使用python實現Virginia無密鑰解密,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
加密
virginia加密是一種多表替換加密方法,通過這種方法,可以有效的解決單表替換中無法應對的字母頻度攻擊。這種加密方法最重要的就是選取合適的密鑰,一旦密鑰被公開,保密性也就無從談起。結合virginia加密原理,給出使用python實現的代碼
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函數代碼:
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函數代碼:
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代碼:
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 # 返回明文
代碼
這是解密部分的全部代碼,注意需要自己添加密文文件的位置
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)
關于“如何使用python實現Virginia無密鑰解密”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。