Quick actions

cmd+k|ctrl+k

Navigation

Languages

XOR Cipher Crack

Snippet info

Language

Python

Visibility

public

Author

rjm27trekkie

Created

2018-02-18T03:41:49Z

Updated

2018-09-29T02:04:02Z

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