XOR Cipher Crack
import re
f = open("cipher.txt")
text = f.read();
bytes = [int(i) for i in re.findall(r"[0-9]+", text)]
chars = [chr(i) for i in bytes]
def shift(data, offset):
return data[offset:] + data[:offset]
def count_same(data, shifted):
count = 0
for x, y in zip(data, shifted):
if x == y:
count += 1
return count
print('guessing key lengths')
for key_len in range(1, 33):
freq = count_same(bytes, shift(bytes, key_len))
print("{0:< 3d} | {1:3d} |".format(key_len, freq) + '=' * (freq // 4))
key_len = int(input("enter most viable key length: "))
from collections import Counter
print('calculating frequencies')
frequencies = []
for i in range(0, key_len):
frequency = Counter()
for ch in chars[i::key_len]:
frequency[ch] += 1
frequencies.append(frequency)
print(frequencies)
print('guesses for most common letters')
key_numbers = []
for frequency in frequencies:
k = ord(frequency.most_common(1)[0][0]) ^ ord(' ')
print('{k} -> \' \''.format(**locals()))
key_numbers.append(k)
others = ''
for val, freq in frequency.most_common(10):
others += chr(ord(val) ^ k) + ' '
print('Other common letters: {others}\n'.format(**locals()))
from itertools import cycle
def decrypt(c_num, k_num):
return ''.join(chr(c^k) for c, k in zip(c_num, cycle(k_num)))
print('decrypting text')
print(decrypt(bytes, key_numbers))
print(sum([ord(i) for i in decrypt(bytes, key_numbers)]))INFO