Skip to content

Instantly share code, notes, and snippets.

@martijnbastiaan
Created March 23, 2014 20:05
Show Gist options
  • Save martijnbastiaan/9729037 to your computer and use it in GitHub Desktop.
Save martijnbastiaan/9729037 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# Heaviliy influenced by: http://tinyurl.com/qe2ht4w
import operator
import collections
import numpy
from functools import partial
from string import ascii_lowercase as alpha
NORMALISED_FREQUENCIES = [
0.64297,0.11746,0.21902,0.33483,1.00000,0.17541,
0.15864,0.47977,0.54842,0.01205,0.06078,0.31688,0.18942,
0.53133,0.59101,0.15187,0.00748,0.47134,0.49811,0.71296,
0.21713,0.07700,0.18580,0.01181,0.15541,0.00583
]
def translator(text, alphabet, key):
return text.translate(str.maketrans(alphabet, key))
def caesar_decode(ciphertext, s):
return translator(ciphertext, alpha, alpha[-s:] + alpha[:-s])
def get_frequencies(text):
array = numpy.zeros(len(alpha), numpy.float64)
for c in text:
ord_c = ord(c)
if ord_c >= 97 and ord_c <= 122:
array[ord_c - 97] += 1.0
#print(max(array))
array /= max(array)
return array
def _get_error(frequencies, i):
return abs(frequencies[i] - NORMALISED_FREQUENCIES[i])
def get_error(text):
frequencies = get_frequencies(text)
return sum(map(partial(_get_error, frequencies), range(len(frequencies))))
def get_minimal_error(text):
texts = (caesar_decode(text, rot) for rot in range(len(alpha) - 1))
return min(texts, key=get_error)
def get_cipher_texts(fd, N):
texts = collections.defaultdict(list)
for i, c in enumerate(fd.read()):
texts[i % N].append(c)
return { i: "".join(chars) for i, chars in texts.items() }
if __name__ == '__main__':
import sys
N = int(sys.argv[1])
cipher = open("cipher.txt")
texts = get_cipher_texts(cipher, N)
partial_solutions = [iter(get_minimal_error(texts[i])) for i in range(N)]
exhausted = False
while not exhausted:
for n in range(N):
try:
print(next(partial_solutions[n]), end="")
except StopIteration:
exhausted = True
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment