public static EnigmaMachine Load(Stream stream) { using var reader = new BinaryReader(stream); //HEADER var buffer = reader.ReadString(); if (buffer != "EGMC") { throw new FormatException("Not a valid Enigma Machine File"); } //ALPHABET buffer = reader.ReadString(); if (buffer != "alph") { throw new FormatException("Not a valid Enigma Machine File"); } var len = reader.ReadInt32(); buffer = reader.ReadString(); var alphabet = new Alphabet(buffer); //AUTORESET var autroreset = reader.ReadBoolean(); //STATOR AND REFLECTOR var list = new string[] { "ETW ", "UKW " }; var wheels = new List <EnigmaWheel>(2); foreach (var item in list) { buffer = reader.ReadString(); if (buffer != item) { throw new FormatException("Not a valid Enigma Machine File"); } buffer = reader.ReadString(); if (buffer != "indx") { throw new FormatException("Not a valid Enigma Machine File"); } len = reader.ReadInt32(); buffer = reader.ReadString(); var indexing = new Alphabet(buffer); buffer = reader.ReadString(); if (buffer != "wire") { throw new FormatException("Invalid/Corrupted Enigma File"); } len = reader.ReadInt32(); buffer = reader.ReadString(); var wiring = new Alphabet(buffer); var wheel = new EnigmaWheel(indexing, wiring); wheels.Add(wheel); } //ROTORS buffer = reader.ReadString(); if (buffer != "ROTS") { throw new FormatException("Invalid/Corrupted Enigma File"); } len = reader.ReadInt32(); var builder = new StringBuilder(); var rotors = new List <Rotor>(); while (true) { builder.Clear(); buffer = reader.ReadString(); if (buffer != "indx") { throw new FormatException("Invalid/Corrupted Enigma File"); } len = reader.ReadInt32(); buffer = reader.ReadString(); var indexing = new Alphabet(buffer); buffer = reader.ReadString(); if (buffer != "wire") { throw new FormatException("Invalid/Corrupted Enigma File"); } len = reader.ReadInt32(); buffer = reader.ReadString(); var wiring = new Alphabet(buffer); var wheel = new EnigmaWheel(indexing, wiring); buffer = reader.ReadString(); if (buffer != "ntch") { throw new FormatException("Invalid/Corrupted Enigma File"); } len = reader.ReadInt32(); for (int t = 0; t < len; t++) { builder.Append(reader.ReadChar()); } var rotor = new Rotor(indexing, wiring, builder.ToString()); rotors.Add(rotor); if (reader.PeekChar() == -1) { break; } } //BUILDER return(new EnigmaMachineBuilder() .WithAlphabet(alphabet) .WithRotors(rotors) .WithStator(wheels[0]) .WithReflector(wheels[1]) .Build()); }
/// <summary> /// When provided, the machine will use the stator and not create its own. /// If not provided, a default stator is created from the alphabet. /// </summary> /// <param name="stator"></param> /// <returns></returns> public EnigmaMachineBuilder WithStator(EnigmaWheel stator) { _stator = stator; return(this); }
/// <summary> /// When provided, the machine will use the reflector and not create it's own. /// If not provided, a random reflector is created from the alphabet. /// </summary> /// <param name="reflector"></param> /// <returns></returns> public EnigmaMachineBuilder WithReflector(EnigmaWheel reflector) { _reflector = reflector; return(this); }
/// <summary> /// Builds an <see cref="EnigmaMachine"/> with the provided parameters. /// </summary> /// <returns></returns> public EnigmaMachine Build() { var shuffle = new Alphabet(_alphabet.ToString()); //the stator: var stator = _stator; if (stator == null) { stator = new EnigmaWheel(_alphabet.ToString(), _alphabet.ToString()); } //the reflector var reflector = _reflector; if (reflector == null) { shuffle.Shuffle(); reflector = new EnigmaWheel(_alphabet.ToString(), shuffle.ToString()); reflector.Reflect(); } //the rotors List <Rotor> rotors; if (_rotors == null) { rotors = new List <Rotor>(); for (int i = 0; i < _rotorCount; i++) { string notches = ""; for (int n = 0; n < _notchCount; n++) { char c; do { int rnd = Horus.Random(0, _alphabet.Count); c = _alphabet[rnd]; } while (notches.Contains(c)); notches += c; } shuffle.Shuffle(); var rotor = new Rotor(_alphabet.ToString(), shuffle.ToString(), notches); rotors.Add(rotor); } } else { rotors = new List <Rotor>(_rotors); } //the actual construction return(new EnigmaMachine(rotors) { Alphabet = _alphabet, AutoReset = _autoReset, Stator = stator, Reflector = reflector, }); }