How to Implement the Vigenère Cipher in Python

Step-by-step guide to implementing the Vigenère Cipher in Python. Understand its mechanism, strengths, and vulnerabilities, with practical examples for encryption and decryption.
  · 7 min read · Updated jun 2024 · Ethical Hacking · Cryptography

Unlock the secrets of your code with our AI-powered Code Explainer. Take a look!

Introduction

In this tutorial, we are going to see how to implement the Vigenère Cipher in Python.  The Vigenère cipher is a method of encrypting alphabetic text using a simple form of polyalphabetic substitution. It was invented by Blaise de Vigenère in the 16th century and was considered unbreakable for centuries. The Vigenère cipher is more secure than a simple Caesar cipher, which is a monoalphabetic substitution cipher.

Before we see how to implement it in Python, let’s understand how it works:

  • Key: The Vigenère cipher uses a keyword or phrase as the key. The key is repeated to match the length of the message.
  • Tableau: A Vigenère table (or Vigenère square) is created, which consists of the alphabet written out 26 times in different rows, each shifted cyclically to the left compared to the previous row.
  A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
  B C D E F G H I J K L M N O P Q R S T U V W X Y Z A
  C D E F G H I J K L M N O P Q R S T U V W X Y Z A B
  D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
  • Encryption: To encrypt a message, each letter in the message is shifted according to the corresponding letter in the key. The row corresponds to the key letter, and the column corresponds to the plaintext letter. The intersection of the row and column gives the ciphered letter.

For example, if the key is KEY and the message is HELLO, the encryption process would be as follows:

   Key:    K E Y K E Y K E Y K E Y K E Y K E Y K E Y K E Y
   Text:   H E L L O H E L L O H E L L O H E L L O H E L L
   Cipher: R I J J V R I J J V R I J J V R I J J V R I J J
  • Decryption: Decryption is the reverse process. Each letter in the ciphertext is shifted back to the original letter using the key.

Python Implementation

Now that we have an idea of how the Vigenère cipher works, let’s see how to implement it in Python.

Install colorama if you haven't already:

$ pip install colorama

Open up a new Python file and follow along. We start by importing the necessary libraries:

# Import sys for system operations and colorama for colored output.
import sys
from colorama import init, Fore

# Initialise colorama
init()

Now, let’s create a function to encrypt a message using the Vigenère cipher. This function will take in a plaintext (message) and key as parameters.

# Function to Encrypt using the Vigenère cipher.
def vigenere_encrypt(plain_text, key):
   encrypted_text = ''
   # Repeat the key to match the length of the plaintext.
   key_repeated = (key * (len(plain_text) // len(key))) + key[:len(plain_text) % len(key)]
   # Iterate through each character in the plaintext.
   for i in range(len(plain_text)):
       # Check if the character is an alphabet letter.
       if plain_text[i].isalpha():
           # Calculate the shift based on the corresponding key letter.
           shift = ord(key_repeated[i].upper()) - ord('A')
           # Encrypt uppercase and lowercase letters separately.
           if plain_text[i].isupper():
               encrypted_text += chr((ord(plain_text[i]) + shift - ord('A')) % 26 + ord('A'))
           else:
               encrypted_text += chr((ord(plain_text[i]) + shift - ord('a')) % 26 + ord('a'))
       else:
           # If the character is not an alphabet letter, keep it unchanged.
           encrypted_text += plain_text[i]
   # Return the final encrypted text
   return encrypted_text

Next, we create a function for the decryption process:

# Decryption function for the Vigenère cipher
def vigenere_decrypt(cipher_text, key):
    decrypted_text = ''
    # Repeat the key to match the length of the ciphertext
    key_repeated = (key * (len(cipher_text) // len(key))) + key[:len(cipher_text) % len(key)]
    # Iterate through each character in the ciphertext
    for i in range(len(cipher_text)):
        # Check if the character is an alphabet letter
        if cipher_text[i].isalpha():
            # Calculate the shift based on the corresponding key letter
            shift = ord(key_repeated[i].upper()) - ord('A')
            # Decrypt uppercase and lowercase letters separately
            if cipher_text[i].isupper():
                decrypted_text += chr((ord(cipher_text[i]) - shift - ord('A')) % 26 + ord('A'))
            else:
                decrypted_text += chr((ord(cipher_text[i]) - shift - ord('a')) % 26 + ord('a'))
        else:
            # If the character is not an alphabet letter, keep it unchanged
            decrypted_text += cipher_text[i]
    # Return the final decrypted text
    return decrypted_text

Finally, we specify the key and accept input from the user:

key = "KEY"
# Get user input (Message to encrypt).
plaintext = input('[!] Enter your message: ')
# Encrypt the plaintext using the Vigenère cipher
cipher_text = vigenere_encrypt(plaintext, key)
# Print the results
print(f"[+] Plaintext: {plaintext}")
print(f"{Fore.GREEN}[+] Ciphertext: {cipher_text}")
# Ask if user wants to decrypt the message (just to see the functionality.)
ask_to_decrypt = input('\n\n[?] Do you want to decrypt the message?\n[?] Y or N: ').lower()
# If user wants to.
if ask_to_decrypt == 'y':
   # Decrypt the ciphertext back to the original plaintext.
   decrypted_text = vigenere_decrypt(cipher_text, key)
   print(f"{Fore.GREEN}[+] Decrypted text: {decrypted_text}")
# If user does not want to.
elif ask_to_decrypt == 'n':
   sys.exit()
# When an invalid input is entered.
else:
   print(f"{Fore.RED}[-] Invalid input.")

Running the Code

We’re done with the code. Let’s run our program to see our results:

$ python vigenere_cipher.py
[!] Enter your message: The Python Code
[+] Ciphertext: Dlc Twdlmx Ayhc

[?] Do you want to decrypt the message?
[?] Y or N: y
[+] Decrypted text: The Python Code

Let’s take some time to talk about the strengths and weaknesses of the Vigenère cipher.

Strengths and Weaknesses

  • Strengths: The Vigenère cipher was considered very secure for a long time, especially when compared to simpler ciphers like the Caesar or Affine cipher. The use of a keyword makes the key longer and more complex.
  • Weaknesses: The Vigenère cipher's main weakness is its susceptibility to frequency analysis. Although it avoids simple letter-to-letter substitution, patterns in the key can still be exploited. Once the key length is determined, the cipher can be broken using various cryptographic techniques.

Cryptanalysis

The Vigenère cipher can be cracked using methods like the Kasiski examination, Friedman test, and index of coincidence to determine the key length. Once the key length is known, the cipher can be treated as multiple Caesar ciphers, and each one can be broken individually.

Despite its vulnerabilities, the Vigenère cipher played an important historical role in the development of cryptographic techniques and understanding of frequency analysis.

Check out similar tutorials:

Finally, if you've enjoyed unraveling the mysteries of the Vigenère cipher with us and are curious to dive deeper into the fascinating world of cryptography using Python, we've got just the thing for you. Our eBook, Cryptography with Python, is designed to be your next step. It's packed with more concepts, techniques, and code examples to help you strengthen your skills and understanding. Whether you're looking to enhance your knowledge for a project, personal interest, or professional development, this eBook is crafted to guide you through the complexities of cryptography in a practical, engaging way. Check it out here.

Happy ciphering ♥

Finished reading? Keep the learning going with our AI-powered Code Explainer. Try it now!

View Full Code Assist My Coding
Sharing is caring!



Read Also



Comment panel

    Got a coding query or need some guidance before you comment? Check out this Python Code Assistant for expert advice and handy tips. It's like having a coding tutor right in your fingertips!