Step-by-step enciphering.
immutable pbCI = plugboard("ABIDEFGHCJKLMNOPQRSTUVWXYZ"); // C <-> I immutable enWh = entryWheel("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); immutable refB = reflector("YRUHQSLDPXNGOKMIEBFZCWVJAT"); immutable rot1 = rotor("EKMFLGDQVZNTOWYHXUSPAIBRCJ", 'Q', 'A'); immutable rot2 = rotor("AJDKSIRUXBLHWTMCQGZNPYFVOE", 'E', 'B'); immutable rot3 = rotor("BDFHJLCPRTXVZNYEIWGAKMUSQO", 'V', 'A'); auto e3 = Enigma!(3, EnigmaType.plugboard)(pbCI, enWh, rot1, rot2, rot3, refB, ['X', 'Q', 'E']); assert(e3('A') == 'K'); assert(e3('a') == 'T'); // A lowercase is automatically converted to an uppercase. assert(e3('5') == '5'); // A non-alphabetical character does not changes assert(e3('Ü') == 'Ü'); // the machine state and will be output as it is. assert(e3('A') == 'Q');
Encipherment is decipherment.
// These have the same settings. auto encipherer = Enigma!2(entryWheelABC, rotorVI, rotorVII, reflectorC, "PY"); auto decipherer = Enigma!2(entryWheelABC, rotorVI, rotorVII, reflectorC, "PY"); foreach (dchar c; "ABCDEFGHIJKLMNOPQRSTUVWXYZ") { auto enciphered = encipherer(c); auto deciphered = decipherer(enciphered); }
A certain equivalence of the M3 and the M4.
// These have the equivalent settings. auto m3 = EnigmaM3(entryWheelABC, rotorIII, rotorII, rotorI, reflectorB /*!*/ , "FOO"); auto m4 = EnigmaM4(entryWheelABC, rotorIII, rotorII, rotorI, rotorBeta('A') /*!*/ , reflectorBThin /*!*/ , "FOOA" /*!*/ ); // FOO*A* // If each machine has just one movable rotor... auto e1 = Enigma!1(entryWheelABC, rotorI, reflectorC /*!*/ , "X"); auto e2fixed = Enigma!(2, EnigmaType.fixedFinalRotor /*!*/ )(entryWheelABC, rotorI, rotorGamma('A') /*!*/ , reflectorCThin /*!*/ , "XA" /*!*/ ); // X*A* foreach (dchar c; "ABCDEFGHIJKLMNOPQRSTUVWXYZ") { assert(m3(c) == m4(c)); assert(e1(c) == e2fixed(c)); }
Encipher with the M4 and decipher with the equivalent M3.
import std.algorithm.comparison : equal; import std.algorithm.iteration : each, map; import std.array : appender; // These have the equivalent settings. auto m4 = EnigmaM4(plugboard("SBCDEGFHIJKLMNOPQRATUVWXYZ"), entryWheelABC, rotorIII('Y'), rotorII('V'), rotorI('R'), rotorBeta, reflectorBThin, "UEQA"); auto m3 = EnigmaM3(plugboard("SBCDEGFHIJKLMNOPQRATUVWXYZ"), entryWheelABC, rotorIII('Y'), rotorII('V'), rotorI('R'), reflectorB, "UEQ"); auto enciphered = appender!dstring; "ABCDEFGHIJKLMNOPQRSTUVWXYZ".map!m4 .each!(c => enciphered.put(c)); assert(enciphered.data == "RIIGSIBEBIZKCTZSSDGQMLSVUX"); auto deciphered = enciphered.data.map!m3; assert(deciphered.equal("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
Predefined existent reflectors.