From 9985bc78556b464920e9ed6c2ac137570eb439d7 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Tue, 15 Jul 2014 08:37:35 +0100 Subject: [PATCH] Keyword ciphers --- cipherbreak.py | 60 -------------------------------------------------- 1 file changed, 60 deletions(-) diff --git a/cipherbreak.py b/cipherbreak.py index 704595a..aba309d 100644 --- a/cipherbreak.py +++ b/cipherbreak.py @@ -5,9 +5,7 @@ import string import collections import norms import logging -from itertools import starmap from segment import segment -from multiprocessing import Pool import matplotlib.pyplot as plt @@ -126,64 +124,6 @@ def affine_break(message, fitness=Pletters): best_adder, best_one_based)[:50])) return (best_multiplier, best_adder, best_one_based), best_fit -def keyword_break(message, wordlist=keywords, fitness=Pletters): - """Breaks a keyword substitution cipher using a dictionary and - frequency analysis. - - >>> keyword_break(keyword_encipher('this is a test message for the ' \ - 'keyword decipherment', 'elephant', KeywordWrapAlphabet.from_last), \ - wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS - (('elephant', ), -52.834575011...) - """ - best_keyword = '' - best_wrap_alphabet = True - best_fit = float("-inf") - for wrap_alphabet in KeywordWrapAlphabet: - for keyword in wordlist: - plaintext = keyword_decipher(message, keyword, wrap_alphabet) - fit = fitness(plaintext) - logger.debug('Keyword break attempt using key {0} (wrap={1}) ' - 'gives fit of {2} and decrypt starting: {3}'.format( - keyword, wrap_alphabet, fit, - sanitise(plaintext)[:50])) - if fit > best_fit: - best_fit = fit - best_keyword = keyword - best_wrap_alphabet = wrap_alphabet - logger.info('Keyword break best fit with key {0} (wrap={1}) gives fit of ' - '{2} and decrypt starting: {3}'.format(best_keyword, - best_wrap_alphabet, best_fit, sanitise( - keyword_decipher(message, best_keyword, - best_wrap_alphabet))[:50])) - return (best_keyword, best_wrap_alphabet), best_fit - -def keyword_break_mp(message, wordlist=keywords, fitness=Pletters, - chunksize=500): - """Breaks a keyword substitution cipher using a dictionary and - frequency analysis - - >>> keyword_break_mp(keyword_encipher('this is a test message for the ' \ - 'keyword decipherment', 'elephant', KeywordWrapAlphabet.from_last), \ - wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS - (('elephant', ), -52.834575011...) - """ - with Pool() as pool: - helper_args = [(message, word, wrap, fitness) - for word in wordlist - for wrap in KeywordWrapAlphabet] - # Gotcha: the helper function here needs to be defined at the top level - # (limitation of Pool.starmap) - breaks = pool.starmap(keyword_break_worker, helper_args, chunksize) - return max(breaks, key=lambda k: k[1]) - -def keyword_break_worker(message, keyword, wrap_alphabet, fitness): - plaintext = keyword_decipher(message, keyword, wrap_alphabet) - fit = fitness(plaintext) - logger.debug('Keyword break attempt using key {0} (wrap={1}) gives fit of ' - '{2} and decrypt starting: {3}'.format(keyword, - wrap_alphabet, fit, sanitise(plaintext)[:50])) - return (keyword, wrap_alphabet), fit - def plot_frequency_histogram(freqs, sort_key=None): -- 2.34.1