Chapter 18 – Hacking the Simple Substitution Cipher 279
remove 'N' from the list of what 'A' could map to. So 'A' then maps
to ['M']. Note that now that 'A' maps to only one letter, we can
remove 'M' from the list of potential letters for every other
key. (This is why there is a loop that keeps reducing the map.)
- letterMapping = copy.deepcopy(letterMapping)
- loopAgain = True
The removeSolvedLettersFromMapping() function searches for any cipherletters in the
letterMapping parameter which have one and only one potential decryption letter. These
cipherletters are considered solved: the cipherletter must decrypt to that one potential decryption
letter. This means that any other cipherletters that have this solved letter can have that letter
removed from their lists of potential decryption letters.
This could cause a chain reaction, because when the one potential decryption letter is removed
from other lists of potential decryption letters, it could result in a new solved cipherletter. In that
case, the program will loop and perform the solved letter removal over the whole cipherletter
mapping again.
The cipherletter mapping in letterMapping is copied on line 87 so that changes made to it in the
function do not affect the dictionary value outside the function. Line 88 creates loopAgain,
which is a variable that holds a Boolean value that tells us if the code found a new solved letter
and needs to loop again. In that case the loopAgain variable is set to True on line 88 so that
the program execution will enter the while loop on line 89.
simpleSubHacker.py
89. while loopAgain:
90. # First assume that we will not loop again:
91. loopAgain = False
At the very beginning of the loop, line 91 will set loopAgain to False. The code assumes that
this will be the last iteration through line 89’s while loop. The loopAgain variable is only set
to True if we find a new solved cipherletter during this iteration.
simpleSubHacker.py
93. # solvedLetters will be a list of uppercase letters that have one
94. # and only one possible mapping in letterMapping
95. solvedLetters = []
96. for cipherletter in LETTERS:
97. if len(letterMapping[cipherletter]) == 1:
98. solvedLetters.append(letterMapping[cipherletter][0])