2016-11-30 51 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

相关问题