Vigenère Cipher Encoder & Decoder

Encrypt and decrypt text using this classic polyalphabetic substitution cipher with a keyword

The keyword will be repeated to match the length of your message. For example, with keyword "KEY": KEYKEYKEYK...

Copied!
Vigenère Cipher Visualization Keyword: KEY

The Vigenère cipher uses a series of different Caesar ciphers based on the letters of a keyword. Each letter of the keyword determines how many positions the corresponding plaintext letter should be shifted. This creates a much stronger encryption than a simple Caesar cipher.

What is a Vigenère Cipher?

The Vigenère cipher is a method of encrypting alphabetic text by using a simple form of polyalphabetic substitution. It was invented by Blaise de Vigenère in the 16th century and remained unbroken for three centuries, earning it the nickname "le chiffre indéchiffrable" (the indecipherable cipher).

How Does Vigenère Cipher Work?

The Vigenère cipher uses a keyword to determine the shift for each letter in the plaintext:

  1. Choose a keyword (e.g., "KEY")
  2. Repeat the keyword to match the length of the plaintext
  3. For each position, use the corresponding keyword letter to determine how many positions to shift
  4. Apply the shift using a method similar to the Caesar cipher

For example, with the keyword "KEY" and plaintext "HELLO":

Plaintext Key Shift Calculation Ciphertext
H (7) K (10) 10 (7 + 10) % 26 = 17 R (17)
E (4) E (4) 4 (4 + 4) % 26 = 8 I (8)
L (11) Y (24) 24 (11 + 24) % 26 = 9 J (9)
L (11) K (10) 10 (11 + 10) % 26 = 21 V (21)
O (14) E (4) 4 (14 + 4) % 26 = 18 S (18)

Decryption

Decryption works similarly but in reverse. For each letter in the ciphertext, we subtract the corresponding key letter value (modulo the alphabet size):

Ciphertext Key Shift Calculation Plaintext
R (17) K (10) 10 (17 - 10 + 26) % 26 = 7 H (7)
I (8) E (4) 4 (8 - 4 + 26) % 26 = 4 E (4)
J (9) Y (24) 24 (9 - 24 + 26) % 26 = 11 L (11)
V (21) K (10) 10 (21 - 10 + 26) % 26 = 11 L (11)
S (18) E (4) 4 (18 - 4 + 26) % 26 = 14 O (14)

Vigenère vs. Caesar Cipher

The Vigenère cipher is significantly stronger than the Caesar cipher because it uses multiple substitution alphabets. This makes simple frequency analysis ineffective because the same letter in the plaintext can be encrypted to different letters in the ciphertext, depending on its position and the corresponding keyword letter.

Understanding the Vigenère Cipher

Historical Background

Although named after Blaise de Vigenère, the cipher was actually first described by Giovan Battista Bellaso in 1553. Vigenère published his own version in 1586, which was a more complex cipher incorporating autokeys. However, the simpler version (which is what we now call the Vigenère cipher) became associated with his name through historical confusion.

For nearly 300 years, the cipher remained unbroken, and was widely considered unbreakable. It wasn't until the 19th century that Friedrich Kasiski published a general method for deciphering Vigenère ciphers in 1863.

Mathematical Representation

Mathematically, the Vigenère cipher can be expressed using modular arithmetic:

Encryption

Ci = (Pi + Ki mod m) mod n

Where:

  • Ci is the i-th character of the ciphertext
  • Pi is the i-th character of the plaintext
  • K is the key
  • m is the length of the key
  • n is the size of the alphabet (26 for standard Latin alphabet)

Decryption

Pi = (Ci - Ki mod m + n) mod n

Where:

  • Pi is the i-th character of the plaintext
  • Ci is the i-th character of the ciphertext
  • K is the key
  • m is the length of the key
  • n is the size of the alphabet (26 for standard Latin alphabet)

The Tabula Recta

The Vigenère cipher is often implemented using a table called the "tabula recta" or "Vigenère square" - a 26×26 table containing the alphabet written out 26 times in different rows, each alphabet shifted cyclically to the left compared to the previous alphabet.

To encrypt, find the row with the first letter of the key, and the column with the first letter of the plaintext. The intersection is the encrypted letter. Repeat for each letter, cycling through the key as needed.

Variants and Extensions

Several variations of the Vigenère cipher have been developed:

  • Autokey Cipher: Instead of repeating the keyword, the plaintext itself is used as the key (after the initial keyword)
  • Running Key Cipher: Uses a text as the key (such as a page from a book), providing an extremely long and non-repeating key
  • Beaufort Cipher: A variant that uses a different formula for encryption where the key letter is subtracted from the plaintext letter
  • Gronsfeld Cipher: Uses numbers instead of letters as the key

Breaking the Vigenère Cipher

Despite its historical reputation as "le chiffre indéchiffrable", the Vigenère cipher can be broken through several attacks:

1. Kasiski Examination

This method, developed by Friedrich Kasiski in 1863, looks for repeated segments in the ciphertext, which often indicate that the same plaintext was encrypted with the same part of the key. The distances between these repetitions can help determine the key length.

2. Friedman Test

Also known as the index of coincidence method, this statistical approach helps determine the key length by analyzing the frequency distribution of characters in the ciphertext.

3. Frequency Analysis

Once the key length is known, the ciphertext can be divided into groups where each group was encrypted with the same key letter. Each group can then be analyzed as a simple substitution cipher.

Security Limitations

While much stronger than simple substitution ciphers like the Caesar cipher, the Vigenère cipher is still not secure by modern standards. Its security relies heavily on the key remaining secret and being at least as long as the message. For secure encryption, modern algorithms like AES, RSA, or ECC should be used instead.

Implementation Examples

Python Implementation

def vigenere_encrypt(text, key):
    result = ""
    key_length = len(key)
    key_as_int = [ord(k.upper()) - ord('A') for k in key]
    
    for i, char in enumerate(text):
        if char.isalpha():
            # Determine if character is uppercase or lowercase
            if char.isupper():
                base = ord('A')
            else:
                base = ord('a')
            
            # Convert to 0-25
            char_as_int = ord(char) - base
            
            # Apply Vigenère encryption formula
            key_index = i % key_length
            encrypted = (char_as_int + key_as_int[key_index]) % 26
            
            # Convert back to ASCII and add to result
            result += chr(base + encrypted)
        else:
            # Keep non-alphabetic characters as they are
            result += char
            
    return result

def vigenere_decrypt(text, key):
    result = ""
    key_length = len(key)
    key_as_int = [ord(k.upper()) - ord('A') for k in key]
    
    for i, char in enumerate(text):
        if char.isalpha():
            # Determine if character is uppercase or lowercase
            if char.isupper():
                base = ord('A')
            else:
                base = ord('a')
            
            # Convert to 0-25
            char_as_int = ord(char) - base
            
            # Apply Vigenère decryption formula
            key_index = i % key_length
            decrypted = (char_as_int - key_as_int[key_index] + 26) % 26
            
            # Convert back to ASCII and add to result
            result += chr(base + decrypted)
        else:
            # Keep non-alphabetic characters as they are
            result += char
            
    return result

JavaScript Implementation

function vigenereEncrypt(text, key) {
    let result = '';
    const keyLength = key.length;
    
    // Convert key to array of shift values (0-25)
    const keyShifts = key.toUpperCase().split('').map(k => 
        k.charCodeAt(0) - 65
    );
    
    // Process each character
    for (let i = 0; i < text.length; i++) {
        const char = text[i];
        
        // Check if character is a letter
        if (/[A-Za-z]/.test(char)) {
            // Determine ASCII offset based on case
            const isUpper = char === char.toUpperCase();
            const base = isUpper ? 65 : 97;
            
            // Convert to 0-25 range
            const charIndex = char.charCodeAt(0) - base;
            
            // Get key shift for this position
            const keyIndex = i % keyLength;
            const shift = keyShifts[keyIndex];
            
            // Apply Vigenère encryption
            const encryptedIndex = (charIndex + shift) % 26;
            
            // Convert back to character and append
            result += String.fromCharCode(base + encryptedIndex);
        } else {
            // Keep non-alphabetic characters as they are
            result += char;
        }
    }
    
    return result;
}

function vigenereDecrypt(text, key) {
    let result = '';
    const keyLength = key.length;
    
    // Convert key to array of shift values (0-25)
    const keyShifts = key.toUpperCase().split('').map(k => 
        k.charCodeAt(0) - 65
    );
    
    // Process each character
    for (let i = 0; i < text.length; i++) {
        const char = text[i];
        
        // Check if character is a letter
        if (/[A-Za-z]/.test(char)) {
            // Determine ASCII offset based on case
            const isUpper = char === char.toUpperCase();
            const base = isUpper ? 65 : 97;
            
            // Convert to 0-25 range
            const charIndex = char.charCodeAt(0) - base;
            
            // Get key shift for this position
            const keyIndex = i % keyLength;
            const shift = keyShifts[keyIndex];
            
            // Apply Vigenère decryption (add 26 to ensure positive result)
            const decryptedIndex = (charIndex - shift + 26) % 26;
            
            // Convert back to character and append
            result += String.fromCharCode(base + decryptedIndex);
        } else {
            // Keep non-alphabetic characters as they are
            result += char;
        }
    }
    
    return result;
}

Conclusion

The Vigenère cipher represents an important advancement in cryptographic history, moving beyond simple monoalphabetic substitution to polyalphabetic substitution. Its resistance to frequency analysis made it considerably more secure than previous ciphers, and its conceptual foundation influenced the development of many subsequent encryption methods. While no longer considered secure for modern applications, understanding the Vigenère cipher provides valuable insights into the evolution of cryptographic techniques and the fundamental principles of encryption.