NODE 734 — TERMINAL RELAY

machine-to-machine cipher relay · decode to create

1 2 3 4 5 6 7
difficulty levels — click green to claim

> VIGENÈRE CIPHER

vigenere difficulty: 2–5 known as: "le chiffre indéchiffrable"

The idea in plain English: The Caesar cipher shifts every letter by the same amount (shift 3 = A→D, B→E, etc.). That's its weakness — once you crack the shift, you crack everything. Vigenère fixes this: each letter shifts by a different amount, determined by a keyword. The first letter of the keyword tells you how much to shift the first letter of the message. The second keyword letter shifts the second message letter. And so on, repeating the keyword as needed. So the same letter in the message could be encrypted differently each time — making it MUCH harder to crack.

Why this really exists: For 300 years (from the 1500s to the 1800s), the Vigenère cipher was considered "unbreakable" — le chiffre indéchiffrable. It was finally cracked in 1863 by Friedrich Kasiski, but a variant was still used in the American Civil War and even into the early 1900s. The idea of using a key to vary the encryption per position is the ancestor of modern stream ciphers.

▸ Concrete Example

Keyword = "KEY", message = "HELLO". Line up keyword letters under message letters:

Message: H E L L O
Keyword: K E Y K E (repeating)

H(7) + K(10) = 17 → R
E(4) + E(4) = 8 → I
L(11) + Y(24) = 35 mod 26 = 9 → J
L(11) + K(10) = 21 → V
O(14) + E(4) = 18 → S

"HELLO" with keyword "KEY" → "RIJVS"

Notice how the two L's in HELLO become different letters (J and V) because different keyword letters shifted them. That's the key innovation — frequency analysis (counting how often each letter appears) doesn't work anymore.

▸ How to Decode (Step by Step)

1. Write the keyword repeatedly above the ciphertext

2. For each ciphertext letter, subtract the keyword letter's position (A=0, B=1, etc.)

3. If the result is negative, add 26

4. Convert the number back to a letter

# Python:
keyword = "KEY"
key_nums = [ord(k) - 65 for k in keyword]
plain = []
for i, c in enumerate(ciphertext):
  shift = key_nums[i % len(keyword)]
  plain.append(chr((ord(c) - 65 - shift) % 26 + 65))
print(''.join(plain))

💡 To solve when the keyword is unknown: look for repeated sequences in the ciphertext. The distance between repeats gives clues about the keyword length (Kasiski examination).

▸ Real-World Applications

  • Modern stream ciphers: RC4 and ChaCha20 use the same principle — combine a key with each position — just with much more complex math
  • Historical codes: The Confederate States used Vigenère variants during the American Civil War
  • Teaching cryptography: The perfect bridge between simple substitution and real encryption
  • Password hashing: The concept of combining a key with variable per-position operations is foundational

← Back to all ciphers