+def vigenere_ic_break(message, target_counts=normalised_english_counts):
+ key_length = vigenere_key_length(message),
+ key = vigenere_find_key(message, key_length)
+ return key
+
+def vigenere_key_length(message):
+ best_length = 0
+ best_ic = 0.0
+ for trial_length in range(1, 20):
+ splits = every_nth(message, trial_length)
+ freqs = [norms.scale(frequencies(s)) for s in splits]
+ ic = sum([sum([f ** 2 for f in fs.values()]) for fs in freqs]) / trial_length
+ logger.debug('Vigenere key length of {0} gives IC of {1}'.
+ format(trial_length, ic))
+ if ic > best_ic:
+ best_length = trial_length
+ best_ic = ic
+ return best_length, best_ic
+
+def vigenere_find_key(message, key_length):
+ splits = every_nth(message, key_length)
+ return ''.join([chr(caesar_break(s)[0] + ord('a')) for s in splits])
+
+