Hacking Secret Ciphers with Python

(Ann) #1
Chapter 21 – Hacking the Vigenère Cipher 347

passing the function value getItemAtIndexOne (not calling the function: note the lack of
parentheses) for the key keyword argument. The value True is passed for the reverse
keyword argument to sort in reverse (that is, descending) order.


vigenereHacker.py
176. allFreqScores.append(freqScores[:NUM_MOST_FREQ_LETTERS])


The NUM_MOST_FREQ_LETTERS constant was set to the integer value 3 on line 9. Once the
tuples in freqScores are sorted, a list containing only the first 3 tuples (that is, the tuples with
the three highest English frequency match scores) is appended to allFreqScores.


After the for loop on line 161 completes, allFreqScores will contain a number of list
values equal to the integer value in mostLikelyKeyLength. (For example, since
mostLikelyKeyLength was 3 , allFreqScores would be a list of three lists.) The first
list value will hold the tuples for the top three highest matching subkeys for the first subkey of the
full Vigenère key. The second list value will hold the tuples for the top three highest matching
subkeys for the second subkey of the full Vigenère key, and so on.


Originally, if we wanted to brute-force through the full Vigenère key, there would be ( 26 ^ key
length) number of possible keys. For example, if the key was ROSEBUD (with a length of 7)
there would be 26 ^ 7 (that is, 8,031,810,176) possible keys.


But by checking the English frequency matching, we’ve narrowed it down to the 4 most likely
letters for each subkey, meaning that there are now only ( 4 ^ key length) possible keys. Using the
example of ROSEBUD (with a length of 7) for a Vigenère key, now we only need to check 4 ^ 7
(that is, 16,384) possible keys. This is a huge improvement over 8 billion!


The end Keyword Argument for print()


vigenereHacker.py
178. if not SILENT_MODE:
179. for i in range(len(allFreqScores)):
180. # use i + 1 so the first letter is not called the "0th" letter
181. print('Possible letters for letter %s of the key: ' % (i + 1),
end='')
182. for freqScore in allFreqScores[i]:
183. print('%s ' % freqScore[0], end='')
184. print() # print a newline

Free download pdf