角色频率评分操作
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了角色频率评分操作相关的知识,希望对你有一定的参考价值。
https://cryptopals.com/sets/1/challenges/3所述的加密挑战是:
Single-byte XOR cipher
The hex encoded string:
1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736
... has been XOR'd against a single character. Find the key, decrypt the message.
You can do this by hand. But don't: write code to do it for you.
How? Devise some method for "scoring" a piece of English plaintext. Character frequency is a good metric. Evaluate each output and choose the one with the best score.
这是解决方案吗? :
由于XOR的反转是XOR,我应该对字符串1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736进行异或,每个字符在a-z
范围内,但我应该如何评分此字符串?角色如何与得分相关?
请注意,该字符串是十六进制的,因此您必须将其解释为一系列十六进制字符(可能是ascii编码)。
Before Encoding
1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736
1b 37 37 33 31 36 3f 78
15 1b 7f 2b 78 34 31 33
3d 78 39 78 28 37 2d 36
3c 78 37 3e 78 3a 39 3b
37 36
After Encoding
77316?x+x413=x9x(7-6<x7>x:9;76
7 7 3 1 6 ? x
+ x 4 1 3
= x 9 x ( 7 - 6
< x 7 > x : 9 ;
7 6
What About Scoring?
评分基本上是将输出与我们期望的输出结果进行比较,并且是开发正式称为启发式的非常重要的概念;有根据的猜测/问题的解决方案。
在英语中,某些字母比其他字母更常见。 'e'经常被引用为英文文本中最常用的字母。字母频率表允许您检查字符串是否可能是英语。换句话说,对解密字符串时的任何猜测进行评分。
为了好玩,您可以编写一个程序来制作频率表。它将扫描明文(例如这个答案),计算每个字母,然后显示使用该字母的文本的百分比。在汇总了足够的样本后,您将拥有自己的频率表!如果您不想编译自己的,请查阅wikipedia article,或搜索其他信息。
另一件需要注意的事情是,当我们转换为ascii时,我们缺少一些数据。某些数据变为无法显示的特殊字符。这提出了另一种可能的评分机制;某些特殊字符不会出现在键盘输入的字符串中,因此使用其中许多字符串的字符串不太可能正确。
How to write the code?
至于如何对解决方案进行编码,您需要通过a-z
范围内的每个ascii字符对每个十六进制字符进行xor。请注意,'each'使用了两次,因此您的代码中可能会有两个for
语句或循环结构。
根据XOR
函数的实现方式,减少迭代的一种聪明方法可能是复制单个ascii字符足够的次数以匹配字符串的长度,然后XOR
这两个值。
在这里我通过ascii'a'XOR:
Input:
1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736
Length of input:
34
Repeat (a in ascii) by length:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Then XOR:
input
repeat
Output:
zVVRPW^tzJUPRXIVLW]V_[XZVW
编辑:
看到很长一段时间过去了,我已经在python中为后代实现了一个解决方案。
import string
import re
in_hex = '1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736'
def take(n, s):
'''yield n-sized chunks from iterable s'''
for i in range(0, n, 2):
yield s[i:i+2]
def hex2str(s):
'''given an ascii string of single-byte hex literals, interpret as ascii'''
return bytes.fromhex(s).decode('ascii')
def string_xor(s, c):
'''given an ascii string s of hexadecimal values, xor each one by char c'''
c = ord(c) # dirty dynamic typing
return ''.join(map(lambda h: chr(ord(h) ^ c), s))
for letter in string.ascii_letters:
result = string_xor(hex2str(in_hex), letter)
# remove ascii control chars
pretty_result = re.sub(r'[x00-x1F]+', '', result)
# print the result and the corresponding letter used to decode
print(f'{letter}: {pretty_result}')
成功的路线:
X: Cooking MC's like a pound of bacon
以上是关于角色频率评分操作的主要内容,如果未能解决你的问题,请参考以下文章