264 http://inventwithpython.com/hacking
Email questions to the author: [email protected]
- else:
If a letter in mapA[letter] exists in mapB[letter], add
that letter to intersectedMapping[letter].
- for mappedLetter in mapA[letter]:
- if mappedLetter in mapB[letter]:
- intersectedMapping[letter].append(mappedLetter)
- return intersectedMapping
- def removeSolvedLettersFromMapping(letterMapping):
Cipher letters in the mapping that map to only one letter are
"solved" and can be removed from the other letters.
For example, if 'A' maps to potential letters ['M', 'N'], and 'B'
maps to ['N'], then we know that 'B' must map to 'N', so we can
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 letters for every other
letter. (This is why there is a loop that keeps reducing the map.)
- letterMapping = copy.deepcopy(letterMapping)
- loopAgain = True
- while loopAgain:
First assume that we will not loop again:
- loopAgain = False
solvedLetters will be a list of uppercase letters that have one
and only one possible mapping in letterMapping
- solvedLetters = []
- for cipherletter in LETTERS:
- if len(letterMapping[cipherletter]) == 1:
- solvedLetters.append(letterMapping[cipherletter][0])
If a letter is solved, than it cannot possibly be a potential
decryption letter for a different ciphertext letter, so we
should remove it from those other lists.
- for cipherletter in LETTERS:
- for s in solvedLetters:
- if len(letterMapping[cipherletter]) != 1 and s in
letterMapping[cipherletter]: - letterMapping[cipherletter].remove(s)
- if len(letterMapping[cipherletter]) == 1:
A new letter is now solved, so loop again.
- loopAgain = True
- return letterMapping