Hacking Secret Ciphers with Python

(Ann) #1

336 http://inventwithpython.com/hacking


Email questions to the author: [email protected]


The code inside line 3 8 ’s for loop will find the repeated sequences in message and calculate
the spacings. On the first iteration, it will find sequences that are exactly 3 letters long. On the
next iteration it will find sequences exactly 4 letters long, and then 5 letters long. (You can
change what sequence lengths the code searches for by modifying the range(3, 6) call on
line 3 8 , but finding repeated sequences of length 3, 4 and 5 seems to work for most ciphertexts.)


vigenereHacker.py
39. for seqStart in range(len(message) - seqLen):
40. # Determine what the sequence is, and store it in seq
41. seq = message[seqStart:seqStart + seqLen]


The for loop on line 39 makes sure that we iterate over every possible substring of length
seqLen in the message string. Line 41 sets the seq variable with the sequence we are looking
for. For example, if seqLen is 3 and message is 'PPQCAXQ', we would want to search for the
following sequences (notice the indexes at the top of the 'PPQCAXQ' string):


Table 21-3. Values of seq from message depending on the value in seqStart.
Indexes: 0123456
On 1 st iteration, seqStart is 0 : 'PPQCAXQ'^ (PPQ starts at index 0 .)
On 2 nd iteration, seqStart is 1 : 'PPQCAXQ'^ (PQC starts at index 1 .)
On 3 rd iteration, seqStart is 2 : 'PPQCAXQ'^ (QCA starts at index 2 .)
On 4 th iteration, seqStart is 3 : 'PPQCAXQ'^ (CAX starts at index 3 .)
On 5 th iteration, seqStart is 4 : 'PPQCAXQ'^ (AXQ starts at index 4 , which is
what len(message) - seqLen
evaluates to and is the last index.)

vigenereHacker.py
43. # Look for this sequence in the rest of the message
44. for i in range(seqStart + seqLen, len(message) - seqLen):
45. if message[i:i + seqLen] == seq:


The for loop on line 4 4 is inside line 39’s for loop and sets i to be the indexes of every
possible sequence of length seqLen in message. These indexes start at seqStart +
seqLen (that is, after the sequence currently in seq) and go up to len(message) -
seqLen (which is the last index where a sequence of length seqLen can be found).


The expression message[i:i + seqLen] will evaluate to the substring of message that
gets checked for being a repeat of seq on line 45. If it is, then we need to calculate the spacing
and add it to the seqSpacings dictionary. This is done on lines 4 6 to 5 2.

Free download pdf