Chapter 18 – Hacking the Simple Substitution Cipher 269
{'A': [], 'C': [], 'B': ['S', 'D'], 'E': [], 'D': [], 'G': [], 'F': [], 'I':
[], 'H': [], 'K': ['R', 'A', 'N'], 'J': [], 'M': [], 'L': ['O', 'N'], 'O': [],
'N': [], 'Q': ['N', 'C', 'R', 'I'], 'P': ['C', 'I', 'P', 'U'], 'S': [], 'R':
['V', 'R', 'T'], 'U': [], 'T': [], 'W': [], 'V': [], 'Y': [], 'X': [], 'Z':
['E']}
This finishes the cipherletter mapping for our second cipherword. Now we need to get the
intersection of the cipherletter mappings in letterMapping1 and letterMapping2 by
passing them to intersectMappings(). Try typing the following into the interactive shell:
intersectedMapping = simpleSubHacker.intersectMappings(letterMapping1,
letterMapping2)
intersectedMapping
{'A': [], 'C': ['T'], 'B': ['S', 'D'], 'E': [], 'D': [], 'G': ['B'], 'F': [],
'I': ['O'], 'H': ['M'], 'K': ['A'], 'J': [], 'M': [], 'L': ['N'], 'O': ['U'],
'N': ['L'], 'Q': ['C'], 'P': ['C', 'I', 'P', 'U'], 'S': [], 'R': ['R'], 'U':
[], 'T': [], 'W': [], 'V': [], 'Y': [], 'X': ['F'], 'Z': ['E']}
The intersected mapping is just a cipherletter mapping. The list of potential decryption letters for
any cipherletter in the intersected mapping will only be the potential decryption letters that were
in the cipherletter’s list in both letterMapping1 and letterMapping2.
For example, this is why intersectedMapping’s list for the 'Z' key is just ['E']:
because letterMapping1 had ['E', 'Y'] but letterMapping2 had ['E']. The
intersection of ['E', 'Y'] and ['E'] is just the potential decryption letters that exist in both
mappings: ['E']
There is an exception. If one of the mapping’s lists was blank, then all of the potential decryption
letters in the other mapping are put into the intersected mapping. This is because in our program a
blank map represents any possible letter can be used since nothing is known about the mapping.
Then we do all these steps for the third cipherword, MPBKSSIPLC. Try typing the following into
the interactive shell:
letterMapping3 = simpleSubHacker.getBlankCipherletterMapping()
wordPat = makeWordPatterns.getWordPattern('MPBKSSIPLC')
candidates = wordPatterns.allPatterns[wordPat]
candidates
['ADMITTEDLY', 'DISAPPOINT']
for i in range(len(candidates)):