The cipher disk, live — press ▶. The outer ring is the fixed plaintext alphabet; the inner ring turns to a new key letter for every position (centre) as it enciphers VIGENERE under the key MANCHESTER BLUFF. The beam maps each plaintext letter (coral) to its ciphertext letter (lime).
For three centuries the Vigenère cipher was le chiffre indéchiffrable — the indecipherable cipher. It defeated every technique that cracked ordinary substitution ciphers, and generals trusted it with the fate of armies. Then, in the nineteenth century, Friedrich Kasiski and Charles Babbage noticed that the cipher carries a periodic fingerprint, and the spell was broken. This notebook reconstructs that break end to end, in runnable Wolfram Language, and ends where the story turns: the one provably unbreakable variant, and why our whole attack evaporates against it.
This notebook is fully runnable. Evaluate the setup cell once, then read top to bottom — every figure, table and result below is produced by the Wolfram Language command shown directly above it, with all of its arguments. The setup cell loads the companion file vigenere.wl (keep it in the same folder as this notebook); it defines the cipher engine, the sample data plain, key, ct, the figure library, and the cipher-disk photograph.
SetDirectory[NotebookDirectory[]];​​Get["vigenere.wl"];
Evaluate the code below to generate the cipher disk animation at the top.
heroDisk["VIGENERE","MANCHESTERBLUFF"]

1. The cipher: a wheel of shifting alphabets

A Caesar cipher shifts every letter by a fixed amount; count the letters and its single peak gives it away instantly. The idea here was to make the shift move: choose a keyword, write it repeatedly above the message, and shift each plaintext letter by the alphabet position of the key letter sitting above it. (It is named for Blaise de Vigenère, though Giovan Battista Bellaso published this exact form in 1553; Vigenère's own 1586 cipher was the stronger autokey.) Encryption is one line of modular arithmetic:
c
i
=(
p
i
+
k
imodL
)mod26
where p, k, c are plaintext, key and ciphertext as numbers 0-25 and L is the key length. Decryption just subtracts. These three lines (and everything else below) live in vigenere.wl; here they are, for the record:
clean[s_]:=ToUpperCase[StringJoin[Select[Characters[s],LetterQ]]];​​toNums[s_]:=ToCharacterCode[clean[s]]-65;​​toStr[ns_]:=FromCharacterCode[Mod[ns,26]+65];
vEncrypt[plain_,key_]:=Module[{p=toNums[plain],k=toNums[key],L=StringLength[key]},toStr[Table[Mod[p[[i]]+k[[Mod[i-1,L]+1]],26],{i,Length[p]}]]];
vDecrypt[cipher_,key_]:=Module[{c=toNums[cipher],k=toNums[key],L=StringLength[key]},toStr[Table[Mod[c[[i]]-k[[Mod[i-1,L]+1]],26],{i,Length[c]}]]];
Writing the key out under the message makes the mechanism — and its fatal flaw — visible at a glance:
streamView["THEVIGENERECIPHER","MANCHESTERBLUFF",17,740]
The key MANCHESTERBLUFF repeats every 15 letters (vertical rule). Identical plaintext that happens to land on the same key offset encrypts the same way — the periodicity that will undo the cipher.
The classical way to perform this by hand is the tabula recta: a 26×26 table whose row r, column c holds letter (r+c) mod 26. Row = plaintext letter, column = key letter, cell = ciphertext letter.
tabulaRecta[7,12,540]
The tabula recta. Highlighted: plaintext row H meets key column M at ciphertext T. The diagonal colour bands are the 26 Caesar shifts stacked together.
Is this just a Caesar cipher? A fair question — and the distinction is the whole point. Freeze the disk at one key letter and every plaintext letter gets the same shift: that single setting is a Caesar cipher (and any one row of the tabula recta is one too). Vigenère is the disk turning — a new shift for every position as the key cycles. So:
Vigenère = a sequence of Caesar ciphers, one per key position.
That one idea cuts both ways. It is what makes the cipher strong (a flat histogram, no single peak to attack) — and, as we will see, it is exactly the seam we pry open: recover the period and the Vigenère falls back apart into a handful of Caesar ciphers, each trivially solved.

2. The intercept

Here is a message enciphered with a 15-letter key we will pretend not to know. The cryptanalyst sees only this:
ct
FHRXPKWGIIFNCUMQRJCZPGGKSFWCJAQDGQIIMGFIFLEFGXENPKASLGRMWYIQQCUKMJJXMEEPWMNRFECIPWMLVJYXJHUPUGYETEITJABJWNYVVZEVFMIFCMKTDIGTLWALXVEPPJWKMRVOSVMLRUOYKJMTRFALWLMDQWYXZNSGKAYLBSEDTJMJDSBHPXKWEPZPNGJZENVOMLLEGQLLJSFSGTLRYMLCBJUUJDIBFPGKMVLDEOWJFHNVWELBIEULHFQKSVUJSMEHVYAIXJMNQQUGWXBGPDYIYTEJJVPWXHZGTWJHALYCWWWLMEUZIWIUNNTFPWMXVSDULFUNEGCISEMEHHBFYQVRTZIUKIKUSYBWUTRTOSHXHKPVYJURRBOWVQBRXFJYXKARRXLVSGHVWPLFRQNFQSILNWSFRCSYTEJQYO
426 letters of noise. A simple frequency count is useless — because the moving key smears every plaintext letter across many ciphertext letters, the histogram is almost flat. The cipher's strength is exactly this flatness. Our entire job is to find the one statistic the moving key cannot hide: its period.

3. Kasiski examination: hunting repeats

Kasiski's 1863 insight: if the same word in the plaintext lines up with the same stretch of key, it produces the same ciphertext. So a repeated chunk in the ciphertext is rarely a coincidence — the gap between two copies is almost always a multiple of the key length. Find the repeats, measure the gaps, and the key length hides among their common divisors.
kasiskiDiagram[ct,"GTL",45,740]
The trigram GTL recurs after Δ = 90 characters. And 90 = 2×3×3×5 — so the key length divides 90.
Collect every repeated trigram, factor every gap, and let the candidate lengths vote:
kasiskiVotes[ct,20]
{{3,7},{15,6},{5,6},{9,5},{10,3},{6,3},{2,3},{7,2},{20,1},{18,1},{16,1},{12,1},{11,1},{8,1},{4,1}}
kasiskiVotesChart[ct,15,20,620]
Factor votes. Small divisors like 3 and 5 always score well (every multiple of 15 is also a multiple of 3 and 5), but 15 is the largest length that keeps winning — our prime suspect.
Those votes are not magic — here is the raw evidence behind them: each repeated trigram, the gaps between its copies, and the candidate lengths (divisors of the gap) it supports. Notice how 15 and its divisors keep reappearing across unrelated trigrams:
kasiskiTable[ct]
trigram
positions
gaps Δ
divisors (2–20)
JYX
86 387
301
7
WLM
157 307
150
2 3 5 6 10 15
YTE
285 420
135
3 5 9 15
TEJ
286 421
135
3 5 9 15
GTL
123 213
90
2 3 5 6 9 10 15 18
MEH
262 339
77
7 11
PWM
72 81 321
9 240
3
Kasiski narrows the field but rarely points to a single answer. For that we need sharper, statistical instruments.

4. The index of coincidence

Pick two letters at random from a text. What is the chance they are the same? In a uniformly random string it is 1/26 ≈ 0.0385. In English, because some letters are common, it is markedly higher — about 0.0667. This probability is the index of coincidence:
IC=
Z
∑
i=A
n
i
(
n
i
-1)
N(N-1)
where nᵢ counts letter i and N is the text length. The IoC is invariant under any fixed Caesar shift — shifting renames letters but preserves how clustered they are. That is the key:
The ciphertext as a whole looks random (≈ 0.040). But here is the move that breaks the cipher: if we guess the period m and read off every m-th letter, that subsequence was all enciphered with the same key letter — it is a pure Caesar shift of English, so its IoC jumps back up to ≈ 0.066. Wrong periods stay flat. Scanning m = 1-20 and plotting the average IoC of the m columns:
Average IoC of the m columns, for each candidate period m. Every wrong guess hugs the random line (0.0385); at m = 15 it leaps to the English line (0.0667). The period is 15.
Friedman's formula even estimates the length directly from the global IoC:
Kasiski said "a divisor of 90"; the index of coincidence says "15"; Friedman's estimate, ≈16, corroborates it (it is only an estimate, and lands one off). The key length is settled.
The same periodicity has a third signature, the one a signal processor would reach for first: autocorrelation. Slide the ciphertext against a copy of itself offset by d places and count how often letters coincide. At offsets that are multiples of the key length the columns realign and coincidences spike:
Letter coincidences at each offset. Spikes at 15 and 30 — multiples of the key length — stand well clear of the random floor 0.0385; every other offset is noise.
So three independent instruments now agree: Kasiski's factor votes, Friedman's estimate, and the per-period index of coincidence. Ranked side by side, period 15 wins on every count:

5. Frequency analysis, one key position at a time

Knowing L = 15 dissolves the hard problem into 15 easy ones. Letters 1, 16, 31, … share one key letter; letters 2, 17, 32, … share the next; and so on. Each such coset is a plain Caesar cipher. To solve a Caesar cipher we slide the English frequency profile against the column's counts and keep the shift that fits best — minimising the chi-squared distance:
For a single column the picture is striking: once we apply the winning shift, the column's letter counts (bars) snap onto the English profile (curve).
Column 1 after its best shift. The recovered distribution (bars) tracks English letter frequencies (curve) — the tell-tale E-T-A-O-N-R-I-S peaks. That shift is the first key letter.
Do this for all 15 columns and the key falls out:

6. The plaintext

With the key in hand, decryption is the line we wrote at the start. The whole attack — period by Kasiski and IoC, key by chi-squared — needed only the ciphertext and one assumption: that the plaintext is ordinary English (that is what the IoC thresholds and the chi-squared fit encode):
From 426 letters of apparent noise, the message reappears. The cipher that resisted Europe for 300 years falls in milliseconds, because a repeating key leaves a periodic signature that no amount of alphabet-shuffling can erase.

7. A real message: Vicksburg, 4 July 1863

This is not a toy. On the day Vicksburg surrendered, a Confederate courier carried a Vigenère-enciphered dispatch — sealed in a glass vial with a bullet, to be thrown in the river if capture loomed — to the besieged General Pemberton. It used one of the Confederacy's three stock keys, MANCHESTER BLUFF. The vial sat unread in a museum for over a century. Here is the intercept:
Running the same analysis on these 221 letters, the per-period IoC again spikes hard at 15 — the method finds the key length in a genuine historical artifact. The frequency attack recovers most of the key, but starved of data (only ~14 letters per column), and working from a transcription that is itself imperfect, it stumbles on the rare-letter positions. Even a half-right key already shows GENL PEMBERTON … JOHNSTON, a crib good enough to finish by hand. Decrypted verbatim with the historical key:
A mostly-legible message, pocked with wrong letters (EXVECT for EXPECT, JOJNSTON for JOHNSTON). The surviving transcriptions of this ciphertext are known to be imperfect, so a verbatim decrypt comes out noisy — and that is its own lesson: real intercepts, and the copies we inherit, are dirty, yet the periodic structure still surrenders the message. Cleaned against the historical record, it reads:
GENL PEMBERTON YOU CAN EXPECT NO HELP FROM THIS SIDE OF THE RIVER LET GENL JOHNSTON KNOW IF POSSIBLE WHEN YOU CAN ATTACK THE SAME POINT ON THE ENEMYS LINE …
It told Pemberton no relief was coming. He had already surrendered. The Confederacy's undoing was not the cipher's mathematics but its key management: a tiny rotation of stock keys (MANCHESTER BLUFF, COMPLETE VICTORY, and late in the war COME RETRIBUTION). A key used over and over is a long message in disguise — exactly the periodicity our attack feeds on.
Earlier we said a half-right key let the analyst finish by hand. Here is exactly how, with a crib: guess a word that surely appears — PEMBERTON, JOHNSTON — and slide it along the ciphertext. At the right alignment, subtracting the crib from the ciphertext (k = c - p) hands you a slice of the key directly. cribHits keeps only the alignments whose recovered fragment really is a slice of the repeating key:
PEMBERTON yields HESTERBLU and JOHNSTON yields CHESTERB — both unmistakable slices of MANCHESTERBLUFF. One good guess, and a chunk of the key drops out — which is precisely why armies guarded their stock phrases, and why reusing three of them was fatal.
A surviving Confederate brass cipher disk — the physical embodiment of the wheel above. Photo by Austin Mills, National Cryptologic Museum, 2005. Licensed CC BY-SA 2.0 via Wikimedia Commons (image unmodified except for scaling).

8. Why this all fails: the one-time pad

Every step of the attack leaned on one fact: the key repeats. Kasiski needs repeats to align; the IoC needs columns enciphered by a single shared letter; the frequency attack needs many letters per column. Take away repetition and the whole machine seizes.
So make the key as long as the message and perfectly random, used exactly once — a one-time pad. Now every column has length one. There are no repeats for Kasiski. The IoC sits at 0.0385 for every candidate period. There is nothing to count.
The same period scan on two ciphertexts of the same plaintext. Left: a repeating 15-letter key — the period rings out. Right: a random one-time pad — dead flat. No signal, no key length, no foothold.
This is not merely harder — it is impossible, and Claude Shannon proved it in 1949. With a truly random pad as long as the message, every plaintext of that length is an equally likely explanation of the ciphertext. ATTACKATDAWN and HOLDYOURFIRE are both perfectly consistent with what the eavesdropper sees; the ciphertext contains literally zero information about which was sent. This is perfect secrecy.
The uncertainty about the message after seeing the ciphertext equals the uncertainty before: the message and ciphertext are statistically independent. The cost is brutal — you need as much shared secret key as you have message, never reused — which is why pads are reserved for the highest-stakes traffic and everything else uses modern ciphers that chase the same goal by other means.
The Vigenère cipher and the one-time pad are the same construction — add a key stream to the plaintext, letter by letter. The only difference is whether the key repeats. That single property is the entire distance between broken in milliseconds and unbreakable forever.

9. One knob: the family of additive ciphers

Everything we have built is one idea seen at three settings. Caesar, Vigenère and the one-time pad all do the same thing — add a key stream to the plaintext, letter by letter, c = p + k (mod 26). They differ on a single knob: how long the key is and whether it repeats.
The whole family on one knob. Turn the Caesar dial anew each letter and you get Vigenère; stretch the key to the length of the message, make it random, and use it once, and you get the one-time pad — provably unbreakable. Turn the last knob the wrong way (reuse a pad) and you tumble straight back into the breakable column.
Read left to right, the key space explodes — 26 keys for Caesar, 26^L for a length-L Vigenère, 26^N for a pad on an N-letter message. But size alone is a trap: a 15-letter Vigenère key already has 26^15 ≈ 1.7×10^21 possibilities and we still cracked it in milliseconds. What protects the one-time pad is not that its key space is bigger — it is that the key never repeats, so the structure our attack feeds on simply is not there.
Nor is the attack specific to Vigenère. Its close cousin the Beaufort cipher enciphers with c = k - p instead of c = p + k — a single sign flip (it is its own inverse, which is why the British Royal Navy liked it). The key still repeats, so every periodic signature we exploited is untouched; only the final per-column step changes sign:
The index of coincidence still leaps at period 15, and re-applying Beaufort recovers the plaintext. Change the rule, keep the period, and the same machine walks straight through.

10. How much ciphertext do you actually need?

We can make the boundary between breakable and unbreakable exact. Shannon's unicity distance is the amount of ciphertext at which only one key still yields sensible plaintext — below it, many keys give plausible decryptions and you cannot be sure; above it, the true key stands alone. It is the key's entropy divided by the language's redundancy:
For an L-letter Vigenère key the key entropy is H(K) = L·log₂ 26 ≈ 4.70 L bits. English carries only about 1.0–1.5 bits of real information per letter (Shannon's estimate) against a 4.70-bit alphabet, so its redundancy is roughly D ≈ 3.2 bits/letter — a standard but model-dependent approximation. Taking D ≈ 3.2 gives U ≈ 1.47 L letters:
A 15-letter key is pinned by barely 22 letters of ciphertext. We fed it 426 (and the real Vicksburg dispatch gave 221) — both an order of magnitude past the threshold, which is exactly why the crack was decisive rather than ambiguous.
Now push the knob to its limit. For a one-time pad the key is as long as the message, L = N, so the ciphertext you need is U ≈ 1.47 N — but the ciphertext you have is only N. You are always short by a factor of 1.47, forever. The unicity distance runs off to infinity, no key is ever singled out, and perfect secrecy is the result rather than an assumption.
Unicity distance U ≈ 1.47 L (ciphertext needed to pin the key) versus the L characters a one-time pad gives you. The lime line is always above the coral one — the pad never supplies enough evidence to choose a key, which is perfect secrecy drawn as a picture.
That 1.5-bit figure was itself a guess. Does the conclusion survive if English really carries anywhere from 1.0 to 1.5 bits of information per letter? Sweep it and see:
Unicity distance of the 15-letter key as the assumed English entropy ranges over Shannon's whole 1.0–1.5 bits/letter band. It stays near 20 letters throughout — an order of magnitude below the 426 we had. The verdict does not depend on pinning the entropy exactly.

11. Where this still bites: reuse, VENONA, and stream ciphers

None of this is a museum piece. The lesson — a key that repeats is a key you can break — runs straight through twentieth-century history and into the ciphers protecting this page.
◼
  • VENONA. Under wartime pressure the Soviet Union reused one-time-pad pages. From 1943 to 1980, US and British cryptanalysts at Arlington Hall exploited that reuse — two messages sharing a pad cancel to c₁⊕c₂ = p₁⊕p₂, pure plaintext-on-plaintext — to read thousands of "perfectly secret" cables and expose atomic spies including Klaus Fuchs and the Rosenbergs. The maths was unbreakable; the operations repeated the key.
  • ◼
  • Modern stream ciphers. Vigenère is an additive stream cipher over ℤ₂₆. Replace the short repeating key with a cryptographically pseudorandom keystream and you get RC4, ChaCha20, AES-CTR: c = p ⊕ keystream, the very same shape, but a keystream that no feasible analysis can distinguish from a true pad.
  • ◼
  • Key and nonce reuse. The Vigenère flaw reappears wherever a keystream is repeated: WEP Wi-Fi (reused RC4 IVs), the "two-time pad," and nonce reuse in AES-GCM (which leaks the authentication key outright). Each is the same periodicity, at a higher altitude.
  • ◼
  • The index of coincidence, our sharpest tool here, is still used today for language identification, fingerprinting unknown encodings, and breaking polyalphabetic and rotor ciphers in cryptanalysis and CTFs.
  • Three centuries of "indecipherable," undone by noticing that a key repeats; a single extra idea — never repeat it — that turns the same cipher unbreakable; and a redundancy argument that says exactly where the line falls. From a brass disk at Vicksburg to the stream cipher securing this notebook, it is one continuous thread.
    — Built in the Wolfram Language. Every figure and result above is produced by the command shown above it; all definitions live in the companion vigenere.wl.

    CITE THIS NOTEBOOK

    Breaking the Vigenère cipher from first principles​
    by Marco Thiel​
    Wolfram Community, STAFF PICKS, June 11, 2026
    ​https://community.wolfram.com/groups/-/m/t/3732049