222 http://inventwithpython.com/hacking
Email questions to the author: [email protected]
- else:
- plaintext += symbol # just append this symbol undecrypted
- return plaintext
Lines 6 1 to 68 are almost identical to the encryptMessage() function’s lines 4 5 to 52. The
only difference is on line 65. In the encryptMessage() function, the symbol index was
multiplied by Key A and then had Key B added to it. In decryptMessage()’s line 65, the
symbol index first has Key B subtracted from it, and then is multiplied by the modular inverse.
Then this number is modded by the size of the symbol set, len(SYMBOLS). This is how the
decryption process undoes the encryption.
Generating Random Keys
It can be difficult to come up with a valid key for the affine cipher, so we will create a
getRandomKey() function that generates a random (but valid) key for the user to use. To use
this, the user simply has to change line 10 to store the return value of getRandomKey() in the
myKey variable:
affineCipher.py
- myKey = getRandomKey()
Now the key that is used to encrypt is randomly selected for us. It will be printed to the screen
when line 17 is executed.
affineCipher.py
- def getRandomKey():
- while True:
- keyA = random.randint(2, len(SYMBOLS))
- keyB = random.randint(2, len(SYMBOLS))
The code in getRandomKey()enters a while loop on line 72 where the condition is True.
This is called an infinite loop, because the loop’s condition is never False. If your program
gets stuck in an infinite loop, you can terminate it by pressing Ctrl-C or Ctrl-D.
The code on lines 73 and 74 determine random numbers between 2 and the size of the symbol set
for keyA and for keyB. This way there is no chance that Key A or Key B are equal to the invalid
values 0 or 1.
affineCipher.py
- if cryptomath.gcd(keyA, len(SYMBOLS)) == 1:
- return keyA * len(SYMBOLS) + keyB