+def affine_encipher_letter(letter, multiplier, adder, multiply_then_add=True):
+ if letter in string.ascii_letters:
+ if letter in string.ascii_uppercase:
+ alphabet_start = ord('A')
+ else:
+ alphabet_start = ord('a')
+ letter_number = ord(letter) - alphabet_start
+ cipher_number = 0
+ if multiply_then_add:
+ cipher_number = (letter_number * multiplier + adder) % 26
+ else:
+ cipher_number = ((letter_number + adder) * multiplier) % 26
+ return chr(cipher_number + alphabet_start)
+ else:
+ return letter
+
+def affine_decipher_letter(letter, multiplier, adder, multiply_then_add=True):
+ if letter in string.ascii_letters:
+ if letter in string.ascii_uppercase:
+ alphabet_start = ord('A')
+ else:
+ alphabet_start = ord('a')
+ cipher_number = ord(letter) - alphabet_start
+ plaintext_number = 0
+ if multiply_then_add:
+ plaintext_number = modular_division_table[multiplier][(cipher_number - adder + 26) % 26]
+ else:
+ plaintext_number = (modular_division_table[multiplier][cipher_number] - adder) % 26
+ return chr(plaintext_number + alphabet_start)
+ else:
+ return letter
+
+def affine_encipher(message, multiplier, adder, multiply_then_add=True):
+ enciphered = [affine_encipher_letter(l, multiplier, adder, multiply_then_add) for l in message]
+ return ''.join(enciphered)
+
+def affine_decipher(message, multiplier, adder, multiply_then_add=True):
+ enciphered = [affine_decipher_letter(l, multiplier, adder, multiply_then_add) for l in message]
+ return ''.join(enciphered)
+
+