使用 python 进行频率分析
Using python for frequency analysis
我正在尝试使用 python 来帮助我破解 Vigenère 密码。我对编程还很陌生,但我已经设法制作了一种算法来分析单个字母的频率。这是我目前所拥有的:
Ciphertext = str(input("What is the cipher text?"))
Letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def LetterFrequency():
LetterFrequency = {'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 Ciphertext.upper():
if letter in Letters:
LetterFrequency[letter]+=1
return LetterFrequency
print (LetterFrequency())
但是有没有办法让我从出现次数最多的字母开始按降序打印答案?现在无论我做什么,答案都是随机显示的。
还有谁知道如何从一大块文本中提取特定的字母来进行频率分析?因此,例如,如果我想将文本“THISISARATHERBORINGEXAMPLE”中的每三个字母放在一起进行分析,我需要得到:
T H I
S I S
A R A
T H E
R B O
R I N
G E X
A M P
L E
通常我必须在记事本或 excel 中手动完成此操作,这需要很长时间。在 python 中有没有办法解决这个问题?
提前致谢,
托尼
对于降序,您可以使用 Counter
:
>>> x = "this is a rather boring example"
>>> from collections import Counter
>>> Counter(x)
Counter({' ': 5, 'a': 3, 'e': 3, 'i': 3, 'r': 3, 'h': 2, 's': 2, 't': 2, 'b': 1, 'g': 1, 'm': 1, 'l': 1, 'o': 1, 'n': 1, 'p': 1, 'x': 1})
至于第二个问题,你可以每 3 次迭代一次。
要排除空格,您可以尝试 @not_a_robot 在评论中提出的建议或
像这样手动删除它:
>>> y = Counter(x)
>>> del y[' ']
>>> y
Counter({'a': 3, 'e': 3, 'i': 3, 'r': 3, 'h': 2, 's': 2, 't': 2, 'b': 1, 'g': 1, 'm': 1, 'l': 1, 'o': 1, 'n': 1, 'p': 1, 'x': 1})
另一种方法,尽管来自@coder 的 collections.Counter
示例是您最好的选择。
from collections import defaultdict
from operator import itemgetter
Letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Ciphertext = "this is a rather boring example"
def LetterFrequency():
LetterFrequency = {letter: 0 for letter in Letters}
for letter in Ciphertext.upper():
if letter in Letters:
LetterFrequency[letter]+=1
return LetterFrequency
def sort_dict(dct):
return sorted(dct.items(), key = itemgetter(1), reverse = True)
print(sort_dict(LetterFrequency()))
打印这个,list
的 tuple
按频率降序排列:
[('A', 3), ('I', 3), ('E', 3), ('R', 3), ('T', 2), ('S', 2), ('H', 2), ('L', 1), ('G', 1), ('M', 1), ('P', 1), ('B', 1), ('N', 1), ('O', 1), ('X', 1), ('Y', 0), ('J', 0), ('D', 0), ('U', 0), ('F', 0), ('C', 0), ('Q', 0), ('W', 0), ('Z', 0), ('K', 0), ('V', 0)]
我正在尝试使用 python 来帮助我破解 Vigenère 密码。我对编程还很陌生,但我已经设法制作了一种算法来分析单个字母的频率。这是我目前所拥有的:
Ciphertext = str(input("What is the cipher text?"))
Letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def LetterFrequency():
LetterFrequency = {'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 Ciphertext.upper():
if letter in Letters:
LetterFrequency[letter]+=1
return LetterFrequency
print (LetterFrequency())
但是有没有办法让我从出现次数最多的字母开始按降序打印答案?现在无论我做什么,答案都是随机显示的。
还有谁知道如何从一大块文本中提取特定的字母来进行频率分析?因此,例如,如果我想将文本“THISISARATHERBORINGEXAMPLE”中的每三个字母放在一起进行分析,我需要得到:
T H I
S I S
A R A
T H E
R B O
R I N
G E X
A M P
L E
通常我必须在记事本或 excel 中手动完成此操作,这需要很长时间。在 python 中有没有办法解决这个问题?
提前致谢,
托尼
对于降序,您可以使用 Counter
:
>>> x = "this is a rather boring example"
>>> from collections import Counter
>>> Counter(x)
Counter({' ': 5, 'a': 3, 'e': 3, 'i': 3, 'r': 3, 'h': 2, 's': 2, 't': 2, 'b': 1, 'g': 1, 'm': 1, 'l': 1, 'o': 1, 'n': 1, 'p': 1, 'x': 1})
至于第二个问题,你可以每 3 次迭代一次。
要排除空格,您可以尝试 @not_a_robot 在评论中提出的建议或 像这样手动删除它:
>>> y = Counter(x)
>>> del y[' ']
>>> y
Counter({'a': 3, 'e': 3, 'i': 3, 'r': 3, 'h': 2, 's': 2, 't': 2, 'b': 1, 'g': 1, 'm': 1, 'l': 1, 'o': 1, 'n': 1, 'p': 1, 'x': 1})
另一种方法,尽管来自@coder 的 collections.Counter
示例是您最好的选择。
from collections import defaultdict
from operator import itemgetter
Letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Ciphertext = "this is a rather boring example"
def LetterFrequency():
LetterFrequency = {letter: 0 for letter in Letters}
for letter in Ciphertext.upper():
if letter in Letters:
LetterFrequency[letter]+=1
return LetterFrequency
def sort_dict(dct):
return sorted(dct.items(), key = itemgetter(1), reverse = True)
print(sort_dict(LetterFrequency()))
打印这个,list
的 tuple
按频率降序排列:
[('A', 3), ('I', 3), ('E', 3), ('R', 3), ('T', 2), ('S', 2), ('H', 2), ('L', 1), ('G', 1), ('M', 1), ('P', 1), ('B', 1), ('N', 1), ('O', 1), ('X', 1), ('Y', 0), ('J', 0), ('D', 0), ('U', 0), ('F', 0), ('C', 0), ('Q', 0), ('W', 0), ('Z', 0), ('K', 0), ('V', 0)]