A Vigenère decoder reverses a polyalphabetic cipher in which each letter is shifted by the matching letter of a repeating keyword. With the key LEMON, the first letter is shifted by L (11), the second by E (4), and so on.
Example
Enter LEMON as the key:
LXFOPVEFRNHRATTACKATDAWNHow the Vigenère cipher works
Write the key under the message, repeating it as needed. Each key letter gives a shift (A = 0, B = 1 … Z = 25), and each message letter is shifted by the key letter under it:
| Plain | A | T | T | A | C | K | A | T | D | A | W | N |
| Key | L | E | M | O | N | L | E | M | O | N | L | E |
| Cipher | L | X | F | O | P | V | E | F | R | N | H | R |
As formulas: C = (P + K) mod 26 to encrypt and P = (C − K) mod 26 to decrypt. Only letters use up key positions. Spaces and punctuation pass through unchanged.
Because the same plaintext letter becomes different ciphertext letters depending on its position, simple frequency analysis doesn't work. This earned it the name "le chiffre indéchiffrable" until Charles Babbage and Friedrich Kasiski broke it in the 19th century.
Autokey is a stronger variant. After the keyword runs out, the plaintext itself becomes the key, so the key never repeats. Select Mode: Autokey for those.
Finding an unknown key
This tool needs the key. If you don't have it:
- Find the key length with the Kasiski method: look for repeated sequences of three or more letters in the ciphertext. The distances between repeats tend to be multiples of the key length.
- Split the text into columns, one per key letter. Each column is a simple Caesar cipher.
- Solve each column by frequency analysis or with the Caesar decoder, and read the key from the shifts.
How to use the Vigenère decoder
- Paste the ciphertext.
- Type the keyword in Key. Case doesn't matter, and non-letters are ignored.
- Choose Vigenère or Autokey and read the plaintext.
Decrypt Vigenère in code
def vigenere_decrypt(text, key):
out, i = [], 0
for c in text:
if c.isalpha():
base = 65 if c.isupper() else 97
k = ord(key[i % len(key)].upper()) - 65
out.append(chr((ord(c) - base - k) % 26 + base))
i += 1
else:
out.append(c)
return "".join(out)
print(vigenere_decrypt("LXFOPVEFRNHR", "LEMON")) # ATTACKATDAWNAt a glance
| Type | Polyalphabetic substitution |
| Key | A keyword, repeated |
| Decrypt | P = (C − K) mod 26 |
| Broken by | Kasiski examination and index of coincidence |
Frequently asked questions
What is the tabula recta?
A 26 × 26 table where each row is the alphabet shifted by one more place. To encrypt, find the plaintext letter's column and the key letter's row; the cell where they meet is the ciphertext letter.
Why is my output almost right but garbled in places?
The key is probably slightly wrong, or the text includes characters that the encoder counted differently. Check the spelling of the key, and whether the encoder skipped non-letters the same way.
Is Vigenère the same as a one-time pad?
Only if the key is truly random, as long as the message and never reused. Then it is a one-time pad and can't be broken. A short repeating keyword is what makes ordinary Vigenère breakable.
Last reviewed · found a mistake? contact@decoder.tools · view as markdown