Detect single-character XOR
One of the 60-character strings in this file has been encrypted by single-character XOR.
Find it.
Your code from #3 should help.)
关于这个,我的想法是读取文件,并将其每行字符串进行challenge3中的操作,最终选择得分最高的的字符串。
对此,我只需要在challenge3的基础上修改一下下就行,但不知为何始终出不来。气
改了很久,最终才发现是一个异或的范围错了。
嗯… 异或的函数实现是基于challenge3的代码的。 其中因为是异或一个单字符,我就直接用了string.ascii_letters。尽管最后是对的答案,但是实际上是不够严谨的。
现在我终于将其改回来了。代价是报错+修改代码+薅头约两个小时,也就是说我可能掉了十几根头发,脑袋有点凉
#set1_4
import string
import re
from operator import itemgetter, attrgetter
latter_frequency = {
'a': .08167, 'b': .01492, 'c': .02782, 'd': .04253,
'e': .12702, 'f': .02228, 'g': .02015, 'h': .06094,
'i': .06094, 'j': .00153, 'k': .00772, 'l': .04025,
'm': .02406, 'n': .06749, 'o': .07507, 'p': .01929,
'q': .00095, 'r': .05987, 's': .06327, 't': .09056,
'u': .02758, 'v': .00978, 'w': .02360, 'x': .00150,
'y': .01974, 'z': .00074, ' ': .15000
}
#s = '1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736'
def English_Scoring(t):
return sum([latter_frequency.get(chr(i),0) for i in t.lower()])
def Single_XOR(s,single_character) :
t = b''
#print(s,single_character)
# s = bytes.fromhex(s)
# t: the XOR'd result
for i in s:
t = t+bytes([i^single_character])
# t = re.sub(r'[\x00-\x1F]+','', t)
#remove the ascii control characters
return t
def ciphertext_XOR(s,single_character) :
_data = []
s = bytes.fromhex(s)
# key = ord (single_character)
# ciphertext = b''
# for i in s :
# ciphertext = ciphertext + bytes([i ^ key])
ciphertext = Single_XOR(s,single_character)
#print(ciphertext)
score = English_Scoring(ciphertext)
data = {
'Single character' : single_character,
'ciphertext' : ciphertext,
'score' : score
}
_data.append(data)
score = sorted(_data, key = lambda score:score['score'], reverse=True)[0]
return score
if __name__ == '__main__':
_data = []
s = open('cryptopals_set1_4.txt').read().splitlines()
for i in s :
# print(i)
for j in range(256):
data = ciphertext_XOR(i,j)
_data.append(data)
best_score = sorted(_data, key = lambda score:score['score'], reverse=True)[0]
print(best_score)
for i in best_score :
print("{}: {}".format(i.title(), best_score[i]))
#print(f'{j}:{t},{score}')