确定密文的字母频率
我正在尝试制作一个工具,用来找出某种密码文本中字母的出现频率。假设这些字母都是小写的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]
现在这段代码只显示了某个字母出现的次数。我该如何打印出这个文件中所有字母的频率呢?
3 个回答
2
如果你想知道一个字母 c 的 相对频率,你需要把字母 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)
11
现代的方法:
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})
17
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