Implementation of Affine Cipher in Python

In this tutorial, we shall implement Affine Cipher in Python. The Affine cipher is a monoalphabetic substitution cipher, meaning it uses fixed substitution over the entire message. Every letter in the input is converted to its numeric equivalent and then converted into another letter using a mathematical function.

In Affine Cipher, the mathematical function used is of the form (ax+b)mod m, where ‘a’ and ‘b’ are the keys and ‘m’ is the length of the alphabet used. If a=1, it becomes a Caesar cipher as the encrypting function becomes a linear shifting encryption (x+b)mod m.

E(x) = (ax + b)mod m 
m: size of the alphabet
(a,b): keys of the cipher.

In this discussion, we assume m=26 as there are 26 characters in the alphabet. Choose ‘a’ such that a and m are co-primes (i.e. gcd(a,m) should be equal to 1).

We use the decryption function to decrypt the ciphertext to plaintext. The decryption function will be of the form a-1 (x-b)mod m, where a-1 is the modular multiplicative inverse of a mod m i.e; a*a-1 = 1 mod m. We convert every letter of the ciphertext into integers and apply the decryption function to retrieve the plain text.

affine cipher

Basically, chr() and ord() are inverse to each other. Extended Euclidean Algorithm egcd() finds the modular inverse of a with respect to m.

Program to Implement Affine Cipher in Python

def egcd(a, b): 
  x,y, u,v = 0,1, 1,0
  while a != 0: 
    q, r = b//a, b%a 
    m, n = x-u*q, y-v*q 
    b,a, x,y, u,v = a,r, u,v, m,n 
  gcd = b 
  return gcd, x, y 

def modinv(a, m): 
  gcd, x, y = egcd(a, m) 
  if gcd != 1: 
    return None # modular inverse does not exist 
  else: 
    return x % m 
 
def encrypt(text, key): 
  #E = (a*x + b) % 26 
  return ''.join([ chr((( key[0]*(ord(t) - ord('A')) + key[1] ) % 26) + ord('A')) for t in text.upper().replace(' ', '') ]) 


def decrypt(cipher, key): 
  #D(E) = (a^-1 * (E - b)) % 26
  return ''.join([ chr((( modinv(key[0], 26)*(ord(c) - ord('A') - key[1])) % 26) + ord('A')) for c in cipher ]) 

# Driver Code to test the above functions 
def main(): 
  text = 'VAMSI KRISHNA'
  key = [7, 20] 

  # calling encryption function 
  enc_text = encrypt(text, key) 

  print('Encrypted Text: {}'.format(enc_text)) 

  # calling decryption function 
  print('Decrypted Text: {}'.format(decrypt(enc_text, key) )) 


if __name__ == '__main__': 
  main() 

Below is the given output of our program:

Encrypted Text: LUAQYMJYQRHU
Decrypted Text: VAMSIKRISHNA

Thank You for reading and Keep Learning 🙂

Also Read: Implement Caesar Cipher in Java

Leave a Reply

Your email address will not be published. Required fields are marked *