Ciphers

Enigma M3

The Wehrmacht machine with rotors I, II, III and reflector B. Rotor positions, ring settings, a plugboard. Reciprocal, so one setting works both ways.
create
create("enigma")
family
Rotor
options
--positions? --rings? --plugboard?
self-inverse
yes
keyspace
26^6 × plugboard configurations
try it
ciphers enigma "ATTACK AT DAWN" --positions MCK --rings BDF --plugboard 'AV BS CG'

One fixed machine: rotors I, II and III in that order from left to right, reflector B, double step of the middle rotor included. Three settings are yours. positions is the three letters in the windows at the start, rings the ring settings, both default AAA. plugboard is up to thirteen letter pairs separated by spaces. Enigma is reciprocal, so decode is encode with the same settings. Only A to Z go through the machine and step the rotors, anything else passes through untouched.

const enigma = create("enigma");
enigma.encode("AAAAA").text; // "BDZGO", the standard test vector
enigma.encode("AAA", { positions: "ADU" }).text; // "EQI", a double-step vector
const settings = { positions: "MCK", rings: "BDF", plugboard: "AV BS CG DL FU HZ IN KM OW RX" };
enigma.encode("SECRETMESSAGE", settings).text; // "KILYLYNVKOEPS"
enigma.decode("KILYLYNVKOEPS", settings).text; // "SECRETMESSAGE"

A letter in two plugboard pairs, a position that isn't three letters, a ring setting with a digit - each is an InvalidOptionError before the machine turns. And the machine never maps a letter to itself. That was its famous flaw, and it's the reason a known plaintext could be slid along a ciphertext at Bletchley.

@agntn/ciphers·MIT license· Classical ciphers, for lessons and puzzles. Not for protecting anything, ever.