Vigenere Cipher Encoder and Decoder

Decode
Encode
const key = "cryptools";
const text = "hello world";
const alphabet = "abcdefghijklmnopqrstuvwxyz";

let i = 0;
const result = [...text]
  .map((v) => {
    const keyIndex = alphabet.indexOf(key[i % key.length]);
    const textIndex = alphabet.indexOf(v);
    if (keyIndex === -1 || textIndex === -1) {
      return v;
    }
    i++;
    return alphabet[(keyIndex + textIndex) % alphabet.length];
  })
  .join("");

console.log(`Ciphering "${text}" using key "${key}": "${result}"`);

The Vigenère cipher

The Vigenère cipher is a more complex application of the Caesar cipher, where it encodes text using a given key in the form of text. It uses a table of shifted Caesar ciphers; the message and key are crossed using the table to encode a letter. This table, called a tabula recta, is shown below.

The encoding process

Say you want to encode the message HELLOWORLD with key CRYPTOOLS. When encoding using a key shorter than the message, the key is repeated so its length is the length of the input text. In this case, this results in key text of CRYPTOOLSC. The encoding process moves through the message sequentially, starting with the first letter and matching it to the first letter of the key. To find the ciphered letter, find the intersection of the current message letter and the current key letter.

The encoding process for the first letter:

  1. Find the message letter at index [0] -> "H"
  2. Find the key letter at index [0] -> "C"
  3. Using the table, find their intersection -> "J"
  4. Repeat for next letter in message

The encoding process for the last letter:

  1. Find the message letter at index [9] -> "D"
  2. Find the key letter at index [9] -> "C"
  3. Using the table, find their intersection -> "F"
  4. Last letter, exit

The resulting encoded text is JVJAHKCCDF.

This process can also be expressed algebraically, where \(C_i\) is the current character at index \(i\) being encoded, and \(K_i\) is the key character being encoded at the same index. These values represent the character's index in the Caesar alphabet.

\(E_K(C_i)=(C_i+K_i)\mod 26\)

Decryption is performed by subtracting the key's shift value instead of adding it.

\(D_K(C_i)=(C_i-K_i)\mod 26\)

More generally, when \(l\) is the length of the key, and \(m\) as the length of the alphabet, encryption and decryption can be written as such:

\(E_K(C_i)=(C_i+K_{i\bmod l})\mod m\)

\(D_K(C_i)=(C_i-K_{i\bmod l})\mod m\)

Vigenère variants

The Beaufort variant is a modification of the Vigenere cipher where the encryption and decryption steps are switched (encryption performs subtraction and decryption performs addition).

Using the same message HELLOWORLD and key CRYPTOOLS, it would result in an encrypted message FNNWVIAGTB.

The Beaufort cipher is a different modification of the Vigenere cipher in which the message index is subtracted from the key index in both encryption and decryption.

So, encryption and decryption can be written as

\(E_K(C_i)=D_K(C_i)=(K_{i\bmod l}-C_i)\mod m\)