The affine cipher is a type of monoalphabetic substitution cipher, wherein each letter in an alphabet is mapped to its numeric equivalent, encrypted using a simple mathematical function, and converted back to a letter. The formula used means that each letter encrypts to one other letter, and back again, meaning the cipher is essentially a standard substitution cipher with a rule governing which letter goes to which. As such, it has the weaknesses of all substitution ciphers.
- - - - - - - - - -
How does it work?
Each letter is enciphered with the function (a * x + b) mod 26, where b is the magnitude of the shift. Let’s say we have a word “secret” and we want to encrypt it with a = 5 and b = 7. These numbers are basically the encryption key.
Now, we have to take the word letter by letter and find the position of every letter in the ABC. Keep in mind that counting starts from 0! Let me help you with the following table:
All we have to do is substitute these number into the formula. The result will be the position of the encrypted letter in the ABC.
Plain text message:
Encrypting the letters:
5 * 18 + 7 mod 26 = 19 5 * 4 + 7 mod 26 = 1 5 * 2 + 7 mod 26 = 17 5 * 17 + 7 mod 26 = 14 5 * 4 + 7 mod 26 = 1 5 * 19 + 7 mod 26 = 24
The encrypt method takes 2 parameters, a coefficients list which will have 2 elements and a message. I created 2 variable for the 2 coefficient and started iterating through the plain message letter by letter. I ignored every letter that is not in the alphabet and simply continued the loop.
Next, I created a new index variable to store the current letter index. For better readability, I decided to store the result of the formula (the encrypted letter index) in a new variable.
Finally, I appended that specific letter from the alphabet to the encrypted_message variable.
for char in message: if char notin ALPHABET: continue index = ALPHABET.find(char) encrypted_char_index = (coefficient_a * index + coefficient_b) % len(ALPHABET) encrypted_message += ALPHABET[encrypted_char_index]
As for the decryption, the procedure is a little different. The decryption formula is a^-1 (x - b) mod 26. For this to work, we have to find the modular multiplicative inverse of a. The modular multiplicative inverse of an integer a is an integer x such that the product a * x is congruent to 1 with respect to the modulus m. The multiplicative inverse of a only exists if a and m are coprime. Hence without the restriction on a, decryption might not be possible.
I started a loop, which iterates through the length of the alphabet. If a * i % 26 equals to 1, then we found our multiplicative inverse and we can continue with the next loop. In the second loop, I calculated the decrypted_char_index by substituting into the formula and at the end, I appended the decrypted letter to the decrypted_message variable.