Three wheels and an odometer. The right one turns every key, the middle one turns when the right one has gone all the way round, the left one when the middle one has. Anybody who has read a car’s mileage knows the shape of it.
Except that it is not quite that, and the part that is not is not a quirk of the wiring or the code — it is a consequence of there being three pawls and only three, each asked to do a job and a half.
The pawls, and what holds them off
Each rotor carries two rings of teeth. On one face, a ratchet: 26 sawteeth, one per letter, which is what a pawl pushes on. On the other, the alphabet ring, a smooth circumference with a single notch cut in it.
A pawl lies in the groove between two rotors. Its tooth is over the ratchet of the rotor on its left; its tip rests on the alphabet ring of the rotor on its right. A spring presses the whole thing inward, and full ring diameter holds it out — tooth clear of the ratchet, the key stroke wasted. Only when the notch comes round under the tip can the pawl fall far enough in for its tooth to reach.
The rightmost pawl has nothing to its right but the fixed entry wheel, which carries no ring at all. Nothing ever holds it out, so it is in the ratchet on every single key. That is why the fast rotor is the fast rotor: not a gear ratio, an absence.
A pawl in a notch is pushing on the notch
Here is the whole piece, and it is one sentence.
The pawl that has fallen into a notch is not resting in it. The bar is about to shove that pawl sideways by one tooth — and the pawl is inside the notch, with the notch’s trailing flank against it. So it pushes two things at once: the ratchet of the rotor on its left, through its tooth, and the alphabet ring of the rotor on its right, through its own body.
Every pawl drives two rotors. One deliberately, one as a side effect nobody asked for.
For the middle pawl this costs nothing: the rotor it drags is the right-hand rotor, which was stepping anyway. For the left pawl it is a second mover on a rotor that already has one. The middle rotor can be advanced by its own pawl, when the right rotor is at its notch; or dragged by the left pawl, when the middle rotor is itself at its notch. And those two happen on consecutive keys.
The walk everyone is shown
Rotors I, II, III, left to right, at ADU:
| key | window | left | middle | right | what happened |
|---|---|---|---|---|---|
| 0 | ADU | · | · | ratchet | — |
| 1 | ADV | · | ratchet | ratchet | turnover |
| 2 | AEW | ratchet | dragged | ratchet | double step |
| 3 | BFX | · | · | ratchet | — |
| 4 | BFY | · | · | ratchet | — |
| 5 | BFZ | · | · | ratchet | — |
| 6 | BFA | · | · | ratchet | — |
| 7 | BFB | · | · | ratchet | — |
| 8 | BFC | · | · | ratchet | — |
D to E to F, on two keys running, with only one full revolution of the right rotor between them. The sprite draws the difference in colour: an orange ratchet is being pushed by a tooth, a green ring is being shoved by a pawl’s flank. At AEW the middle rotor is green.
The notch is on the ring, not on the wiring
Worth saying because it is the one part of the machine that moves relative to the other: the notch is cut in the alphabet ring, and the Ringstellung turns that ring against the wiring core. So setting the ring moves the wiring out from under the notch, and never the notch out from under the window.
Which is why turnovers are quoted as window letters and are always the same ones, and why the mnemonic works at all:
| rotor | notch (window letter) | steps into |
|---|---|---|
| I | Q | R |
| II | E | F |
| III | V | W |
| IV | J | K |
| V | Z | A |
| VI | Z, M | A, N |
| VII | Z, M | A, N |
| VIII | Z, M | A, N |
Royal Flags Wave Kings Above — the letters I–V step into.
What it costs the odometer
Three wheels of 26 is 17,576 positions, and a plain odometer would visit all of them before repeating. This one does not, and the gap is not small change.
| quantity | value | as |
|---|---|---|
| positions a three-rotor odometer has | 17,576 | 26³ |
| positions the stepping visits | 16,900 | 26 × 25 × 26 |
| positions it never returns to | 676 | 26² |
| …of those, with no predecessor at all | 650 | 26 × 25 |
| right rotor moves | 16,900 | 650 revolutions |
| middle rotor moves | 676 | 26 revolutions |
| left rotor moves | 26 | 1 revolution |
| double steps | 26 | one key in 650 |
| a 250-letter signal | 250 keys | 1.48% of the period |
The 25 in the middle is the double step, counted: the middle rotor passes through 26 letters but is only held at 25 of them for a full revolution of the rotor below it. At its own notch letter it is pushed straight out again on the following key, and that one letter of the 26 is the entire difference between 17,576 and 16,900.
Six hundred and fifty positions that cannot happen
The missing positions are not scattered. Ask which positions have no predecessor — which readings the machine can never show one key after showing anything at all — and the answer is a single row:
| what | value |
|---|---|
| count | 650 |
| middle rotor letters involved | E |
| right rotor letters not involved | W |
| left rotor letters involved | all 26 |
E is rotor II’s notch letter. W is where rotor III lands after its turnover. The middle rotor can only arrive at its own notch by being pushed there by the rotor below, and the rotor below only pushes when it is stepping into W. So E in the middle window with anything but W on the right is a reading the machine cannot step into — only one you can set by hand, and then it leaves on the next key and never comes back.
That is the red row in the demo’s grid: 26 columns, 25 of them dead.
The navy made it worse
Rotors VI, VII and VIII carry two notches each, at Z and at M. More turnovers per revolution sounds like more movement, and it is — the middle rotor is driven twice as often. It is also, for the odometer, straightforwardly destructive:
| rotor order | period | cycles | no predecessor | left moves | middle moves | double steps |
|---|---|---|---|---|---|---|
| I-II-III | 16,900 | 1 | 650 | 26 | 676 | 26 |
| III-II-I | 16,900 | 1 | 650 | 26 | 676 | 26 |
| II-V-IV | 16,900 | 1 | 650 | 26 | 676 | 26 |
| I-V-III | 16,900 | 1 | 650 | 26 | 676 | 26 |
| I-II-VI | 8,450 | 2 | 624 | 26 | 676 | 26 |
| I-VI-III | 8,112 | 2 | 1,300 | 26 | 338 | 26 |
| VI-VII-VIII | 4,056 | 4 | 1,248 | 26 | 338 | 26 |
Any three of I–V, in any order, give 16,900 — the period does not care which rotors or which order, only that each has one notch. Put a two-notch rotor on the right and the period halves. Put one in the middle and it halves again and the reachable positions fall into two cycles that never meet. All three navy rotors: 4,056 keys, four separate cycles, a quarter of what the army machine managed.
The left rotor turns exactly once per period in every one of these, which is the clearest way to say what the period is: it is however long the slow rotor takes to come home, and everything else is a question of how fast the middle one feeds it.
None of this is a break. 250 letters is a long signal and 1.48% of one army period; no operator ever wrapped round. It is the more ordinary kind of defect — a machine whose designers could tell you its key space to the digit, and whose stepping gear quietly disagreed with them by four per cent, for reasons that are entirely visible if you take the lid off.
Reuse
source/double-step.mjs is framework-free, with no canvas in it. The stepping
is 20 lines; the rest is the drawing and the counting.
ROTORS— the eight service rotors and their notch letters, withturnoveras the letters they step into (the mnemonic, as data).pawls(pos, notches)— which pawls can reach their ratchet this stroke.stepis the keystroke,driverssays how each rotor is being moved (ratchet,dragged, or nothing), andisDoubleStepis the one bit worth watching.sequence(start, order, n)— the odometer walk, with each reading tagged turnover or double.census(order)— period, number of separate cycles, positions with no predecessor, per-rotor move counts, double steps. Walked over all 17,576 positions and peeled, not solved; the shape of the functional graph is the answer and there is no closed form worth trusting over a sweep.orphanPlane(order)— the same census folded onto the middle × right plane, which is the picture.renderFrame(cfg)→ an indexed bitmap;paintBitmapputs it on a 2D context at an integer scale.strokeShape(phase)is the keystroke: rest, drive, dwell, return.glyphand a 5×7 face, because the whole mechanism exists to move one letter past a window.validateGeometry()checks the story rather than the syntax: that the odometer really reads ADU ADV AEW BFX, that the fast rotor is never held off, that the period is 16,900 and something is unreachable, that every rotor’s turnover letters agree with its notches, and that a held-off pawl clears the ratchet while a seated one bites.
The demo is demo/index.html with its own copy of the module (ADR-0002). It
sizes itself to its viewport, so the site’s full-screen button just works.
Space bar is a key press.
What is derived here, and what isn’t
- Derived, and the drawing is built from it: every angle is a multiple of
360/26; the drive stroke is exactly one tooth of ratchet measured on the
ratchet’s own circumference; the notch is one letter wide; the pawl’s lift is
the depth of the notch, and is checked to clear the ratchet when held out and
to reach it when seated. Which rotor is lit, and in which colour, comes from
drivers()rather than from the animation. - Measured, not asserted:
scripts/measure.mjsregenerates every table above by walking the stepping.scripts/screenshot-demo.mjsboots the demo in a real browser and checks fourteen assertions against the live page’s own readouts — that ADV is an ordinary turnover and AEW is not, that the middle rotor at AEW is dragged rather than driven, that one period returns to AAA, that the middle rotor moved 676 times and the left exactly 26, and that the navy rotors cut the period to 4,056 in four pieces. Any page error fails the run. - Chosen: the rotors are drawn spread along their axle so all three faces show at once — in the machine they are stacked face to face and all you see through the lid is their edges and three windows. The pawls are drawn crossing in front of the rings for the same reason; a real pawl lies in the groove between two rotors and is in front of nothing. Everything here is in teeth and pixels, not millimetres: the mechanism’s only real dimension is 26, and a scale drawing would say less.
- Not modelled, and it doesn’t matter to the lesson: the wiring. There are no contacts, no reflector, no plugboard and no letter being enciphered in any of this — the stepping gear does not know what the rotors are wired to, and neither does the sprite. The Ringstellung is discussed and not drawn, for the same reason: it moves the core under the ring and the notch does not care.
- Not modelled, and it does: the keyboard linkage is one lever here and several in the machine, and the return stroke is drawn as the pawls riding back over the sawteeth — which is what a ratchet is for, and which I have not confirmed is how this one is actually relieved. Nothing in the counting depends on it: the return moves no rotor either way. The pawl bar’s stroke is drawn at one tooth, which is what it has to be, and not at whatever over-travel the real linkage carries.