【问题标题】:Determining Letter Frequency Of Cipher Text确定密文的字母频率
【发布时间】:2010-11-02 19:21:29
【问题描述】:

我正在尝试制作一个工具来查找某种类型的密文中字母的频率。 让我们假设它都是小写的 a-z 没有数字。编码后的消息在 txt 文件中

我正在尝试构建一个脚本来帮助破解替换密码或可能的转置密码。

到目前为止的代码:

cipher = open('cipher.txt','U').read()
cipherfilter = cipher.lower()
cipherletters = list(cipherfilter)

alpha = list('abcdefghijklmnopqrstuvwxyz')
occurrences = {} 
for letter in alpha:
    occurrences[letter] = cipherfilter.count(letter)
for letter in occurrences:
    print letter, occurrences[letter]

到目前为止,它所做的只是显示一个字母出现了多少次。 我将如何打印此文件中找到的所有字母的频率。

【问题讨论】:

  • 问题是什么?请注意,您正在扫描 cipherfilter 26 次!
  • "到目前为止,它所做的只是显示一个字母出现了多少次。我将如何打印在这个文件中找到的所有字母的频率。"什么?频率是一个字母出现的次数。如果它显示一个字母出现了多少次,那就是每个字母出现的频率。这似乎有效。你有什么问题?

标签: python encryption cryptography


【解决方案1】:
import collections

d = collections.defaultdict(int)
for c in 'test':
    d[c] += 1

print d # defaultdict(<type 'int'>, {'s': 1, 'e': 1, 't': 2})

来自文件:

myfile = open('test.txt')
for line in myfile:
    line = line.rstrip('\n')
    for c in line:
        d[c] += 1

对于defaultdict容器这个天才,我们必须感谢和赞美。否则我们都会做这样的傻事:

s = "andnowforsomethingcompletelydifferent"
d = {}
for letter in s:
    if letter not in d:
        d[letter] = 1
    else:
        d[letter] += 1

【讨论】:

    【解决方案2】:

    如果您想知道字母 c 的 relative frequency,则必须将 c 出现的次数除以输入的长度。

    以亚当为例:

    s = "andnowforsomethingcompletelydifferent"
    n = len(s) # n = 37
    

    并将每个字母的绝对频率存储在

    dict[letter]
    

    我们通过以下方式获得相对频率:

    from string import ascii_lowercase # this is "a...z"
    for c in ascii_lowercase:
        print c, dict[c]/float(n)
    

    把它们放在一起,我们会得到这样的结果:

    # get input
    s = "andnowforsomethingcompletelydifferent"
    n = len(s) # n = 37
    
    # get absolute frequencies of letters
    import collections
    dict = collections.defaultdict(int)
    for c in s:
        dict[c] += 1
    
    # print relative frequencies
    from string import ascii_lowercase # this is "a...z"
    for c in ascii_lowercase:
        print c, dict[c]/float(n)
    

    【讨论】:

    • 你不应该使用dict作为变量名。
    【解决方案3】:

    现代方式:

    from collections import Counter
    
    string = "ihavesometextbutidontmindsharing"
    Counter(string)
    #>>> Counter({'i': 4, 't': 4, 'e': 3, 'n': 3, 's': 2, 'h': 2, 'm': 2, 'o': 2, 'a': 2, 'd': 2, 'x': 1, 'r': 1, 'u': 1, 'b': 1, 'v': 1, 'g': 1})
    

    【讨论】:

      最近更新 更多