我试图为caeser密码创建频率分析,但我似乎无法获得输出

时间:2016-11-30 15:04:13

标签: python

我目前正在编写一个代码,我想计算密文中使用的字母的频率,然后将其与ETAOINSHRDLCUMWFGYPBVKJXQZ进行比较。然后,我希望它建议在解密时使用密钥但是我无法从当前编码中获得输出。

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

1 个答案:

答案 0 :(得分: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()

令人失望(但并不奇怪),每次运行此代码时,可能会获得不同的结果。这是不行的,但它发生的原因是collections.Counter().most_common(),当项目具有相同的计数时,使用任意顺序返回它们。但话又说回来,随着要加密的文本的大小增加,具有完全相同计数的两个字母的可能性会消失。将n设置为1也有帮助(代码为ceasar密钥提供了一个建议)。