2016-11-30 87 views
0

我目前正在編寫一個代碼,我想計算在密文中使用的字母的頻率,然後將其與ETAOINSHRDLCUMWFGYPBVKJXQZ進行比較。然後,我希望它提供解密時使用的密鑰,但是我無法從當前編碼獲得輸出。我試圖創建一個caeser密碼的頻率分析,但我似乎無法得到一個輸出

englishLetterFreq = {'E', 'T', 'A', 'O', 'I', 'N', 'S', 'H', 'R', 'D', 'L', 'C', 'U', 'M', 'W', 'F', 'G', 'Y', 'P', 'B', 'V', 'K', 'J', 'X', 'Q', 'Z'} 
ETAOIN = 'ETAOINSHRDLCUMWFGYPBVKJXQZ' 
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 


def getLetterCount(message): 
    letterCount = {'A': 0, 'B': 0, 'C': 0, 'D': 0, 'E': 0, 'F': 0, 'G': 0, 'H': 0, 'I': 0, 'J': 0, 'K': 0, 'L': 0, 'M': 0, 'N': 0, 'O': 0, 'P': 0, 'Q': 0, 'R': 0, 'S': 0, 'T': 0, 'U': 0, 'V': 0, 'W': 0, 'X': 0, 'Y': 0, 'Z': 0} 

    for letter in message.upper(): 
     if letter in LETTERS: 
      letterCount[letter] +=1 
      print('LETTERS {}'.format(letterCount)) 
    return letterCount 

def getItemAtIndexZero(x): 
    return x[0] 


def getFrequencyOrder(message): 
    letterToFreq = getLetterCount(message) 
    letterToFreq = {} 
    for letter in LETTERS: 
     if letterToFreq[letter] not in freqToletter: 
      freqToLetter[letterToFreq[letter]] = [letter] 
     else: 
      freqToLetter[letterToFreq[letter]].append(letter) 

    for freq in freqToLetter: 
     freqToLetter[freq].sort(key=ETAOIN.find, reverse=True) 
     freqToLetter[freq] = ".join(freqToLetter[freq])" 
     freqPairs = list(freqToLetter.items()) 
     freqPairs.sort(key=getItemAtIndexZero, reverse=True) 
     freqOrder = [] 
     for freqPair in freqPairs: 
      freqOrder.append(freqPair[1]) 
     return".join(freqOrder)" 


def englishFreqMatchScore(message): 

    freqOrder = getFrequencyOrder(message) 
    matchScore = 0 
    for commonLetter in ETAOIN[:6]: 
     if commonLetter in freqOrder[:6]: 
      matchScore += 1 
    for uncommonLetter in ETAOIN[-6:]: 
     if uncommonLetter in freqOrder[-6:]: 
      matchScore += 1 
      print("{}",englsishFreqMatchScore) 
    return matchScore 
+0

您的代碼格式出錯了。請參閱[Markdown幫助 - 代碼和預格式化文本](http://stackoverflow.com/editing-help#code)和[編輯]您的文章。 – Kevin

+0

一般說明。這是稍微先進的,但看看https://docs.python.org/2/library/collections.html#collections.Counter這將爲您節省很多時間,並在將來用這種類型的任務 –

+0

爲什麼要在下面一行覆蓋它時調用getLetterCount – Navidad20

回答

0

看看下面的內容。我很抱歉沒有糾正你的代碼,但有時重寫某些東西比糾正它更容易。隨意問我是否有不清楚的地方。

from collections import Counter 


def decr(text, jump): 
    alpha = 'abcdefghijklmnopqrstuvwxyz' 
    decryption = '' 
    for char in text.lower(): 
     ind = alpha.find(char) 
     if ind != -1: 
      decryption += alpha[ind - jump] 
     else: 
      decryption += char 
    return decryption 

to_dec = r'Max yheehpbgz mhhe teehpl rhn mh xgvkrim t mxqm pbma t lbfiex hyylxm tezhkbmaf - telh dghpg tl Vtxltk vbiaxk. By rhn tkx nlbgz 13 tl max dxr, max kxlnem bl lbfbetk mh tg khm13 xgvkrimbhg. By rhn nlx "znxll" tl max dxr, max tezhkbmaf mkbxl mh ybgw max kbzam dxr tgw wxvkriml max lmkbgz ur znxllbgz. B telh pkhmx t lftee tkmbvex (pbma lhnkvx inuebvtmbhg) tuhnm ybgwbgz max kbzam dxr bg tg ngdghpg vhgmxqm hy tg xgvkrimxw mxqm. By rhn ptgm mh dghp fhkx, B abzaer kxvhffxgm mabl uhhd.' 

alpha = 'abcdefghijklmnopqrstuvwxyz' 
freq = 'etaoinsrhdlucmfywgpbvkxqjz' 
n = 3 

c = Counter(''.join(x for x in to_dec.lower() if x in alpha)) 
order = ''.join(x[0] for x in c.most_common()) 

f = lambda x: alpha.find(x[0]) - alpha.find(x[1]) 
nums = [f(x) if f(x) >= 0 else f(x) + 26 for x in zip(order, freq)] 

d = Counter(nums) 

for i in d.most_common(n): 
    key = i[0] 
    print('Trying Ceasar with n = {}'.format(key)) 
    print(decr(to_dec, key)) 
    print() 

Dissapointingly足夠的(但不奇怪),每次運行這段代碼時,你可能會得到不同的結果。這是一個禁止發生,但它發生的原因是collections.Counter().most_common()哪些項目具有相同的計數時,返回任意命令。但是,再次,隨着進行加密的文本的大小增加,具有完全相同計數的兩個字母的可能性被破壞。將n設置爲1也有幫助(代碼提供ceasar密鑰的一個建議)。

+0

謝謝您的回覆。你在加密文本中提到的書是什麼? – coder123

相關問題