private void OnRotorHitNotch(Rotor rotor, bool forward) { var index = Rotors.IndexOf(rotor); if (index == -1) { throw new NullReferenceException("The rotor that hit the notch was not found"); } if (index == Rotors.Count - 1) { return; //the last rotor, no need to rotate } //Perform any necessary double stepping if (DoubleStep && index + 1 >= Rotors.Count) { if (Rotors[index + 1].IsTurnOver()) { Rotors[index + 1].Rotate(); } } index++; //Rotate the next rotor; Rotors[index].Rotate(forward); }
public char Encode(char character, bool moveRotor = true) { if (!char.IsLetter(character)) { return(character); } if (moveRotor) { MoveRotors(); } var encodedCharacter = character; foreach (var rotor in Rotors) { encodedCharacter = rotor.Encode(encodedCharacter); } encodedCharacter = Reflector.Reflect(encodedCharacter); foreach (var rotor in Rotors.AsEnumerable().Reverse()) { encodedCharacter = rotor.InverseEncode(encodedCharacter); } return(encodedCharacter); }
public Settings(MachineType typ, ReflectorType refTyp, RotorName[] rotors, int[] ringPos, string[] plugs) : this(typ, refTyp) { MachineType = typ; ReflectorType = refTyp; if (MachineType == MachineType.M4K) { if (refTyp == ReflectorType.B_Dunn) { Rotors.Add(new RotorSetting(RotorName.Beta, 0)); } else { Rotors.Add(new RotorSetting(RotorName.Gamma, 0)); } } Rotors.Add(new RotorSetting(RotorName.I, 0)); Rotors.Add(new RotorSetting(RotorName.II, 0)); Rotors.Add(new RotorSetting(RotorName.III, 0)); Plugs.Clear(); for (int i = 0; i < rotors.Length; i++) { if (i <= Rotors.Count) { Rotors[i].Name = rotors[i]; if (i <= ringPos.Length) { Rotors[i].RingSetting = ringPos[i]; } } } for (int i = 0; i < 10; i++) { if (i <= plugs.Length) { Plugs.Add(new PlugSetting(plugs[i])); } } }
/// <summary> /// Creates a new instance of an Enigma Machine with the provided rotors /// </summary> /// <param name="rotors">The rotors to be used by the Enigma Machine</param> public EnigmaMachine(IEnumerable <Rotor> rotors) { Rotors.CollectionChanged += OnRotorsChanged; Rotors.AddRange(rotors); }
/// <summary> /// Rotates the rotor to the appropriate slot /// </summary> /// <param name="r"></param> /// <param name="offset"></param> public void RotateRotor(Rotors r, int offset) { int lastIndex = r.GetCipher().Length - 1; r.Rotate(offset <0 || offset> lastIndex ? lastIndex : offset); }
/// <summary> /// Determines if the next rotor needs to be rotated /// </summary> /// <param name="num">the rotor index</param> /// <returns></returns> public bool CheckIfRotate(int num) { return(rotors[num].GetLastAlphabetLetter() == Rotors.GetRotorAdvancements(rotors[num].CipherNumber)); }
/// <summary> /// Sets the rotor with the passed parameter /// </summary> /// <param name="index">the rotor number</param> /// <param name="rotor">the rotor settings</param> public void SetRotor(int index, Rotors rotor) { rotors[index] = rotor; }
/// <summary> /// Gets the letter at the given index in the alphabet string /// as well as the index of the letter in the cipher /// </summary> /// <param name="l">the letter to retrieve</param> /// <param name="i">the index of the letter</param> /// <param name="r">the rotor to search through</param> public static void LeftToRight(ref char l, ref int i, Rotors r) { l = r.LetterInAlphabet(i); i = r.CipherLetterIndex(l); }
/// <summary> /// Gets the letter at the given index in the cipher /// as well as the index of the letter in the alphabet string /// </summary> /// <param name="l">the letter to retrieve</param> /// <param name="i">the index of the letter</param> /// <param name="r">the rotor to search through</param> public static void RightToLeft(ref char l, ref int i, Rotors r) { l = r.LetterInCipher(i); i = r.AlphabetLetterIndex(l); }
public Settings(MachineType typ, ReflectorType refTyp, params object[] args) : this(typ, refTyp) { MachineType = typ; ReflectorType = refTyp; if (MachineType == MachineType.M4K) { if (refTyp == ReflectorType.B_Dunn) { Rotors.Add(new RotorSetting(RotorName.Beta, 0)); } else { Rotors.Add(new RotorSetting(RotorName.Gamma, 0)); } } Rotors.Add(new RotorSetting(RotorName.I, 0)); Rotors.Add(new RotorSetting(RotorName.II, 0)); Rotors.Add(new RotorSetting(RotorName.III, 0)); Plugs.Clear(); List <RotorName> rotorNames = new List <RotorName>(); List <int> ringSettings = new List <int>(); List <string> plugSettings = new List <string>(); foreach (var item in args) { if (item is RotorName) { rotorNames.Add((RotorName)item); continue; } if (item is int) { ringSettings.Add((int)item); continue; } if (item is string) { plugSettings.Add((string)item); continue; } } for (int i = 0; i < rotorNames.Count; i++) { if (i <= Rotors.Count) { Rotors[i].Name = rotorNames[i]; if (i <= ringSettings.Count) { Rotors[i].RingSetting = ringSettings[i]; } } } for (int i = 0; i < 10; i++) { if (i <= plugSettings.Count) { Plugs.Add(new PlugSetting(plugSettings[i])); } } }
/// <summary></summary> public override string ToString() { return(Reflector.ToString() + " / " + Rotors.ToOneString(" / ") + " / Plugs: " + PlugBoard.ToString()); }
/// <summary> /// Full constructor for a Rotor. /// </summary> /// <param name="chosenRotor">Which Rotor from the Rotors enumeration you want.</param> /// <param name="ringOffset">Position A on the wiring map matches this position on the indicator ring.</param> /// <exception cref="InvalidRotorChoiceException"/> /// <exception cref="InvalidLetterException"/> public Rotor(Rotors chosenRotor, int ringOffset) { RightToLeftMapping = new LinkedList<int>(); LeftToRightMapping = new LinkedList<int>(); // Bail early and hard if conditions aren't perfect. if (!Enum.IsDefined(typeof(Rotors), chosenRotor) || chosenRotor == Rotors.BadRotor) { throw new InvalidRotorChoiceException("Sorry, The chosen rotor must be Rotors.I and Rotors.Gamma."); } if (ringOffset < 0 || ringOffset > 25) { throw new InvalidLetterException("Sorry, the ring offset must be between 0 and 25."); } // Create the Dictionaries SortedDictionary<EnigmaAlphabet, EnigmaAlphabet> rightToLeftMappingDictionary = new SortedDictionary<EnigmaAlphabet, EnigmaAlphabet>(); SortedDictionary<EnigmaAlphabet, EnigmaAlphabet> leftToRightMappingDictionary = new SortedDictionary<EnigmaAlphabet, EnigmaAlphabet>(); // The Right to Left direction is represented directly by the string // from RotorStrings. So I can just directly map it. // This is a lot cleaner in the Java version due to Java's much superior // handling of Enumerations. for (int index = 0; index < RotorStrings[(int)chosenRotor].Length; index++) { rightToLeftMappingDictionary.Add((EnigmaAlphabet)index, (EnigmaAlphabet)Enum.Parse(typeof(EnigmaAlphabet), RotorStrings[(int)chosenRotor].Substring(index, 1))); } // The Left to Right direction is built by inverting the Key to Value relationship // in the Right to Left dictionary. foreach (KeyValuePair<EnigmaAlphabet, EnigmaAlphabet> kvp in rightToLeftMappingDictionary) { leftToRightMappingDictionary.Add(kvp.Value, kvp.Key); } // now that I have created a sorted key to value mapping convert those mappings into lists. RightToLeftMapping = new LinkedList<int>(rightToLeftMappingDictionary.Values.Cast<int>()); LeftToRightMapping = new LinkedList<int>(leftToRightMappingDictionary.Values.Cast<int>()); indicatorTransferPositon = new int[2]; indicatorTransferPositon[0] = RotorTurnoverList[(int)chosenRotor, 0]; indicatorTransferPositon[1] = RotorTurnoverList[(int)chosenRotor, 1]; Offset = ringOffset; // Shift the rotor's wiring forward until the correct offset between the indicator and the rotor's wiring is achieved if (ringOffset != 0 ) { Shift(ringOffset); } _Indicator = 0; }
/// <summary> /// Quick constructor for a Rotor. Useful when you aren't changing the offset of the wiring. /// </summary> /// <param name="chosenRotor">Which Rotor from the Rotors enumeration you want.</param> /// <seealso cref="Rotor(Rotors, int)"> /// This constructor has the same constraints and exceptions as the full constructor for Rotor. /// </seealso> public Rotor(Rotors chosenRotor) : this(chosenRotor, 0) { }