Pick a depth. Each prompt opens in your AI pre-loaded with the lesson. Click a row to preview the prompt.
Enigma was an electromechanical polyalphabetic substitution cipher with a key space of roughly 10^23 — enormous for 1939, and the machine was believed unbreakable by its operators throughout the war. Polish cryptanalysts (Rejewski, Różycki, Zygalski) and then the British team at Bletchley Park (Turing, Welchman, et al.) broke it anyway, and the lessons are foundational. First: a large key space is not enough — Enigma had structural weaknesses (no letter ever encrypted to itself, doubly-enciphered message keys, a known-plaintext 'cribs' attack surface from predictable German military preambles). Second: operational discipline matters as much as algorithm strength — operator errors (reusing rotor positions, predictable indicator choices) gave Bletchley far more leverage than the algorithm's mathematical weaknesses. Third: automation breaks ciphers — the Bombe machine industrialised guess-and-check in a way the Germans never anticipated, foreshadowing how every modern cryptanalytic advance from differential cryptanalysis to GPU password cracking depends on raw computational throughput. Modern ciphers must therefore be designed against automated attackers with massive parallel compute, not just clever humans with paper.
An Enigma machine is a sequence of rotors that each implement a fixed substitution, plus a reflector that bounces the signal back through the rotors in reverse. The rotors step like an odometer between keypresses, so the effective substitution changes every character. The plugboard ('Steckerbrett') swaps pairs of letters before and after the rotor stack. Critically, the reflector means encryption is involutive (E(E(x)) = x with the same settings) — and also that no letter ever maps to itself, which became the single most exploited weakness.
<that ciphertext>, (0,0,0)) — verify decryption recovers the plaintext (involution property of the reflector).// main.go — run: go run main.go
// Toy Enigma showing the rotor/reflector structure.
// For understanding only — do not use as a real cipher.
package main
import (
"fmt"
"strings"
)
const alph = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
// Three historical I/II/III rotor wirings (Wehrmacht Enigma I)
const (
rotorI = "EKMFLGDQVZNTOWYHXUSPAIBRCJ"
rotorII = "AJDKSIRUXBLHWTMCQGZNPYFVOE"
rotorIII = "BDFHJLCPRTXVZNYEIWGAKMUSQO"
reflectorB = "YRUHQSLDPXNGOKMIEBFZCWVJAT"
)
func indexOf(s string, c byte) int {
return strings.IndexByte(s, c)
}
func rotorForward(c byte, wiring string, position int) byte {
idx := (indexOf(alph, c) + position) % 26
return alph[(indexOf(alph, wiring[idx])-position+26*26)%26]
}
func rotorBack(c byte, wiring string, position int) byte {
idx := (indexOf(alph, c) + position) % 26
return alph[(indexOf(wiring, alph[idx])-position+26*26)%26]
}
func enigmaStep(c byte, positions [3]int) byte {
// Forward through three rotors
c = rotorForward(c, rotorIII, positions[2])
c = rotorForward(c, rotorII, positions[1])
c = rotorForward(c, rotorI, positions[0])
// Reflector
c = reflectorB[indexOf(alph, c)]
// Backward through three rotors
c = rotorBack(c, rotorI, positions[0])
c = rotorBack(c, rotorII, positions[1])
c = rotorBack(c, rotorIII, positions[2])
return c
}
func enigma(text string, startPositions [3]int) string {
pos := startPositions
var out []byte
for _, ch := range strings.ToUpper(text) {
if ch >= 'A' && ch <= 'Z' {
// Step the fastest rotor before encrypting (simplified)
pos[2] = (pos[2] + 1) % 26
if pos[2] == 0 {
pos[1] = (pos[1] + 1) % 26
if pos[1] == 0 {
pos[0] = (pos[0] + 1) % 26
}
}
out = append(out, enigmaStep(byte(ch), pos))
}
}
return string(out)
}
func main() {
ct := enigma("ATTACKATDAWN", [3]int{0, 0, 0})
fmt.Println("ciphertext:", ct)
// Decrypt by running the same machine from the same starting positions
fmt.Println("recovered :", enigma(ct, [3]int{0, 0, 0}))
// Demonstrate the "no letter encrypts to itself" property
collisions := 0
plain := "ATTACKATDAWN"
for i := range plain {
if plain[i] == ct[i] {
collisions++
}
}
fmt.Println("self-mappings:", collisions) // always 0 — exploited at Bletchley
}go run main.go