276 http://inventwithpython.com/hacking
Email questions to the author: [email protected]
Adding Letters to a Cipherletter Mapping
simpleSubHacker.py
38. def addLettersToMapping(letterMapping, cipherword, candidate):
The addLettersToMapping() function attempts to make sure that every letter in the
candidate can be mapped to a letter in the cipherword. It checks over each letter in candidate
and adds its corresponding letter in cipherword to letterMapping if it wasn't already
there.
For example, if 'PUPPY' is our candidate word for the 'HGHHU' cipherword, the
addLettersToMapping() function will change letterMapping so that the key 'H' has
'P' added to its list of potential decryption letters. Then the function will change the key 'G' so
that its list has 'U' appended to it.
If the letter is already in the list of potential decryption letters, the addLettersToMapping()
will not add a letter to the list. We can skip adding 'P' to the 'H' key the next two times since
it’s already been done. Finally, the function will change the key 'U' so that it has 'Y' in its list
of potential decryption letters.
The code in this function assumes that len(cipherword) is the same as len(candidate).
simpleSubHacker.py
49. letterMapping = copy.deepcopy(letterMapping)
To avoid changing the original dictionary value passed for the letterMapping parameter, line
49 will copy the dictionary in letterMapping and make this copy the new value in
letterMapping. (We have to do this because letterMapping was passed a copy of a
dictionary reference value, instead of a copy of the dictionary value. See the “List Reference”
section in Chapter 10 for an explanation of references.)
simpleSubHacker.py
50. for i in range(len(cipherword)):
Line 50 will iterate over each index in the string in cipherword. We need the index (which is
stored in the variable i) because the potential decryption letter to be added will be
candidate[i] for the cipherletter cipherword[i].
simpleSubHacker.py
51. if candidate[i] not in letterMapping[cipherword[i]]: