return (keyword, wrap_alphabet), fit
def monoalphabetic_break_hillclimbing(message, max_iterations=10000000,
- fitness=Pletters):
+ alphabet=None, fitness=Pletters):
ciphertext = unaccent(message).lower()
- alphabet = list(string.ascii_lowercase)
- random.shuffle(alphabet)
- alphabet = ''.join(alphabet)
+ if not alphabet:
+ alphabet = list(string.ascii_lowercase)
+ random.shuffle(alphabet)
+ alphabet = ''.join(alphabet)
return monoalphabetic_break_hillclimbing_worker(ciphertext, alphabet,
max_iterations, fitness)
def monoalphabetic_break_hillclimbing_mp(message, workers=10,
- max_iterations = 10000000, fitness=Pletters, chunksize=1):
+ max_iterations = 10000000, alphabet=None, fitness=Pletters, chunksize=1):
worker_args = []
ciphertext = unaccent(message).lower()
for i in range(workers):
- alphabet = list(string.ascii_lowercase)
- random.shuffle(alphabet)
- alphabet = ''.join(alphabet)
- worker_args.append((ciphertext, alphabet, max_iterations, fitness))
+ if alphabet:
+ this_alphabet = alphabet
+ else:
+ this_alphabet = list(string.ascii_lowercase)
+ random.shuffle(this_alphabet)
+ this_alphabet = ''.join(this_alphabet)
+ worker_args.append((ciphertext, this_alphabet, max_iterations, fitness))
with Pool() as pool:
breaks = pool.starmap(monoalphabetic_break_hillclimbing_worker,
worker_args, chunksize)
with Pool() as pool:
helper_args = [(message, trans, fillcolumnwise, emptycolumnwise,
fitness)
- for trans in translist.keys()
+ for trans in translist
for fillcolumnwise in [True, False]
for emptycolumnwise in [True, False]]
# Gotcha: the helper function here needs to be defined at the top level
return max(results, key=lambda k: k[1])
def amsco_break(message, translist=transpositions, patterns = [(1, 2), (2, 1)],
+ fillstyles = [AmscoFillStyle.continuous,
+ AmscoFillStyle.same_each_row,
+ AmscoFillStyle.reverse_each_row],
fitness=Pbigrams,
chunksize=500):
"""Breaks an AMSCO transposition cipher using a dictionary and
(5, 0, 6, 1, 3, 4, 2): ['fourteen'], \
(6, 1, 0, 4, 5, 3, 2): ['keyword']}, \
patterns=[(1, 2)]) # doctest: +ELLIPSIS
- (((2, 0, 5, 3, 1, 4, 6), (1, 2)), -709.4646722...)
+ (((2, 0, 5, 3, 1, 4, 6), (1, 2), <AmscoFillStyle.continuous: 1>), -709.4646722...)
>>> amsco_break(amsco_transposition_encipher(sanitise( \
"It is a truth universally acknowledged, that a single man in \
possession of a good fortune, must be in want of a wife. However \
(5, 0, 6, 1, 3, 4, 2): ['fourteen'], \
(6, 1, 0, 4, 5, 3, 2): ['keyword']}, \
patterns=[(1, 2), (2, 1)], fitness=Ptrigrams) # doctest: +ELLIPSIS
- (((2, 0, 5, 3, 1, 4, 6), (2, 1)), -997.0129085...)
+ (((2, 0, 5, 3, 1, 4, 6), (2, 1), <AmscoFillStyle.continuous: 1>), -997.0129085...)
"""
with Pool() as pool:
- helper_args = [(message, trans, pattern, fitness)
- for trans in translist.keys()
- for pattern in patterns]
+ helper_args = [(message, trans, pattern, fillstyle, fitness)
+ for trans in translist
+ for pattern in patterns
+ for fillstyle in fillstyles]
# Gotcha: the helper function here needs to be defined at the top level
# (limitation of Pool.starmap)
breaks = pool.starmap(amsco_break_worker, helper_args, chunksize)
return max(breaks, key=lambda k: k[1])
def amsco_break_worker(message, transposition,
- pattern, fitness):
+ pattern, fillstyle, fitness):
plaintext = amsco_transposition_decipher(message, transposition,
- fillpattern=pattern)
+ fillpattern=pattern, fillstyle=fillstyle)
fit = fitness(sanitise(plaintext))
logger.debug('AMSCO transposition break attempt using key {0} and pattern'
- '{1} gives fit of {2} and decrypt starting: {3}'.format(
- transposition, pattern, fit,
+ '{1} ({2}) gives fit of {3} and decrypt starting: '
+ '{4}'.format(
+ transposition, pattern, fillstyle, fit,
sanitise(plaintext)[:50]))
- return (transposition, pattern), fit
+ return (transposition, pattern, fillstyle), fit
def hill_break(message, matrix_size=2, fitness=Pletters,
def plot_frequency_histogram(freqs, sort_key=None):
- x = range(len(freqs.keys()))
- y = [freqs[l] for l in sorted(freqs.keys(), key=sort_key)]
+ x = range(len(freqs))
+ y = [freqs[l] for l in sorted(freqs, key=sort_key)]
f = plt.figure()
ax = f.add_axes([0.1, 0.1, 0.9, 0.9])
ax.bar(x, y, align='center')
ax.set_xticks(x)
- ax.set_xticklabels(sorted(freqs.keys(), key=sort_key))
+ ax.set_xticklabels(sorted(freqs, key=sort_key))
f.show()