X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=cipher.py;h=0e22a2a85bbc0afa5c6dc1b5caaf6c80459fcb2e;hb=fd02f7a4423120f5c73b4038678cee7836a659ca;hp=bd07596815fd629ddf348b5bca12fbd75f080a2f;hpb=61d82c1ce520c37cf00d829e8f856c5fb672266a;p=cipher-tools.git diff --git a/cipher.py b/cipher.py index bd07596..0e22a2a 100644 --- a/cipher.py +++ b/cipher.py @@ -51,6 +51,14 @@ for a in range(26): c = (a * b) % 26 modular_division_table[b][c] = a +def letters(text): + """Remove all non-alphabetic characters from a text + >>> letters('The Quick') + 'TheQuick' + >>> letters('The Quick BROWN fox jumped! over... the (9lazy) DOG') + 'TheQuickBROWNfoxjumpedoverthelazyDOG' + """ + return ''.join([c for c in text if c in string.ascii_letters]) def sanitise(text): """Remove all non-alphabetic characters and convert the text to lowercase @@ -60,8 +68,9 @@ def sanitise(text): >>> sanitise('The Quick BROWN fox jumped! over... the (9lazy) DOG') 'thequickbrownfoxjumpedoverthelazydog' """ - sanitised = [c.lower() for c in text if c in string.ascii_letters] - return ''.join(sanitised) + # sanitised = [c.lower() for c in text if c in string.ascii_letters] + # return ''.join(sanitised) + return letters(text).lower() def ngrams(text, n): """Returns all n-grams of a text @@ -160,11 +169,14 @@ def frequencies(text): ('h', 2), ('i', 1), ('j', 1), ('k', 1), ('l', 1), ('m', 1), ('n', 1), ('o', 4), ('p', 1), ('q', 1), ('r', 2), ('t', 2), ('u', 2), ('v', 1), ('w', 1), ('x', 1), ('y', 1), ('z', 1)] + >>> frequencies('abcdefabcdef')['x'] + 0 """ - counts = collections.defaultdict(int) - for c in text: - counts[c] += 1 - return counts + #counts = collections.defaultdict(int) + #for c in text: + # counts[c] += 1 + #return counts + return collections.Counter(c for c in text) letter_frequencies = frequencies def deduplicate(text): @@ -643,11 +655,12 @@ def scytale_break(message, """ best_key = 0 best_fit = float("inf") + ngram_length = len(next(iter(target_counts.keys()))) for key in range(1, 20): if len(message) % key == 0: plaintext = scytale_decipher(message, key) counts = message_frequency_scaling(frequencies( - ngrams(sanitise(plaintext), 2))) + ngrams(sanitise(plaintext), ngram_length))) fit = metric(target_counts, counts) logger.debug('Scytale break attempt using key {0} gives fit of ' '{1} and decrypt starting: {2}'.format(key,