Hacking Secret Ciphers with Python

(Ann) #1
Chapter 15 – The Affine Cipher 221

To encrypt it, we need to calculate the index of the encrypted letter. We multiply this symIndex
by keyA and add keyB, and mod the number by the size of the symbol set (that is, the
expression len(SYMBOLS)). We mod by len(SYMBOLS) because the affine cipher has a
similar “wrap-around” issue that the Caesar cipher had. Modding by len(SYMBOLS) handles
the “wrap-around” by ensuring the calculated index is always between 0 up to (but not including)
len(SYMBOLS). The number that we calculate will be the index in SYMBOLS of the encrypted
character, which is concatenated to the end of the string in ciphertext.


Everything that happens in the above paragraph was done on line 49.


If symbol was not in our symbol set, then symbol is concatenated to the end of the
ciphertext string on line 51.


affineCipher.py


  1. return ciphertext


Once we have iterated through each character in the message string, the ciphertext variable
should contain the full encrypted string. This string is returned from encryptMessage().


The Affine Cipher Decryption Function


affineCipher.py


  1. def decryptMessage(key, message):

  2. keyA, keyB = getKeyParts(key)

  3. checkKeys(keyA, keyB, 'decrypt')

  4. plaintext = ''

  5. modInverseOfKeyA = cryptomath.findModInverse(keyA, len(SYMBOLS))


The decryptMessage() function is almost the same as the encryptMessage(). Lines 56
to 58 are equivalent to lines 44 to 46.


However, instead of multiplying by Key A, the decryption process needs to multiply by the
modular inverse of Key A. The mod inverse can be calculated by calling
cryptomath.findModInverse(). This function was explained in the previous chapter.


affineCipher.py


  1. for symbol in message:

  2. if symbol in SYMBOLS:


  3. decrypt this symbol



  4. symIndex = SYMBOLS.find(symbol)

  5. plaintext += SYMBOLS[(symIndex - keyB) * modInverseOfKeyA %
    len(SYMBOLS)]

Free download pdf