示例#1
0
        ///<inheritdoc/>
        public override string Run(string input, bool forward)
        {
            var output = new StringBuilder();

            int indexer = 0;

            foreach (var c in input)
            {
                if (indexer == Key.Length)
                {
                    indexer = 0;
                }
                var steps = Alphabet.IndexOf(Key[indexer]) * (forward ? 1 : -1);

                output.Append(Alphabet.WrapChar(c, steps));
                indexer++;
            }

            return(output.ToString());
        }
示例#2
0
        /// <summary>
        /// A special run for the Enigma. Simulates a key press and returns a result.
        /// </summary>
        /// <param name="input">The character that has been depressed</param>
        /// <returns>The output, i.e the character that will be lit in the lamp</returns>
        public virtual char Run(char input)
        {
            //Rotate the FastRotor
            Rotors[0].Rotate();

            //Get the index of the letter in the alphabet:
            int index = Alphabet.IndexOf(input);

            //Pass the current to the Stator:
            index = Stator.GetPath(index, true);

            //Pass the current through successive rotors:
            for (int i = 0; i < Rotors.Count; i++)
            {
                index = Rotors[i].GetPath(index, true);
            }

            //Pass the current the Reflector
            index = Reflector.GetPath(index, true);

            //Pass through the rotors in reverse:
            for (int i = Rotors.Count - 1; i > -1; i--)
            {
                var rotor = Rotors[i];
                index = rotor.GetPath(index, false);
            }

            //Pass the current through the Stator:
            index = Stator.GetPath(index, false);

            var result = Alphabet[index];

            //perform plugboard simulation:
            if (Plugboard != null)
            {
                result = Plugboard.Simulate(result);
            }
            return(result);
        }
示例#3
0
        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());
        }
示例#4
0
        public void Save(Stream stream)
        {
            //header
            using var writer = new BinaryWriter(stream);

            //Header
            writer.Write("EGMC");

            //Alphabet
            writer.Write("alph");
            writer.Write(Alphabet.Count);
            writer.Write(Alphabet.ToString());

            //Whether we autoreset
            writer.Write(AutoReset);

            //Stator Indexing:
            writer.Write("ETW ");
            writer.Write("indx");
            writer.Write(Stator.Indexing.Count);
            writer.Write(Stator.Indexing.ToString());

            //Stator Wiring
            writer.Write("wire");
            writer.Write(Stator.Wiring.Count);
            writer.Write(Stator.Wiring.ToString());

            //Reflector Indexing
            writer.Write("UKW ");
            writer.Write("indx");
            writer.Write(Reflector.Indexing.Count);
            writer.Write(Reflector.Indexing.ToString());

            //Reflector Wiring
            writer.Write("wire");
            writer.Write(Reflector.Wiring.Count);
            writer.Write(Reflector.Wiring.ToString());

            //Rotors
            writer.Write("ROTS");
            writer.Write(Rotors.Count);

            foreach (var rotor in Rotors)
            {
                //Indexing
                writer.Write("indx");
                writer.Write(rotor.Indexing.Count);
                writer.Write(rotor.Indexing.ToString());

                //Wiring
                writer.Write("wire");
                writer.Write(rotor.Wiring.Count);
                writer.Write(rotor.Wiring.ToString());

                //Turnover Notch
                writer.Write("ntch");
                writer.Write(rotor.TurnOver.Count);
                foreach (var notch in rotor.TurnOver)
                {
                    writer.Write(notch);
                }
            }
        }
示例#5
0
 /// <summary>
 /// Creates a rotor from the specified configuration
 /// </summary>
 /// <param name="indexing">The index etching/></param>
 /// <param name="wiring">The wiring etching</param>
 /// <param name="turnOvers">A string, each <see cref="char"/> representing a turnover point</param>
 public Rotor(Alphabet indexing, Alphabet wiring, string turnOvers) : base(indexing, wiring)
 {
     TurnOver = new List <char>(turnOvers);
 }
示例#6
0
        ///<inheritdoc/>
        public override string Run(string input, bool forward)
        {
            var keytable = new Alphabet(Alphabet.ToString())
            {
                Dimensions = Alphabet.Dimensions
            };

            var distinct = Key.Distinct().ToList();

            for (int i = 0; i < distinct.Count; i++)
            {
                keytable.Move(distinct[i], i);
            }

            if (input.Length % 2 != 0)
            {
                input += Alphabet[Alphabet.Count - 1];
            }

            var multiplier = forward ? 1 : -1;
            var output     = new StringBuilder();

            //Let the ciphering begin:
            for (int i = 0; i < input.Length; i += 2)
            {
                var a = keytable.DimensionsOf(input[i]);
                var b = keytable.DimensionsOf(input[i + 1]);

                var newA = new Dimensions(b.X, a.Y);
                var newB = new Dimensions(a.X, b.Y);

                if (a.X == b.X || a.Y == b.Y)
                {
                    newA = a;
                    newB = b;
                    //SamePoint
                    if (a == b)
                    {
                        newA.X                     = PrefferredOrientation == PrefferredOrientation.Horizontal ?
                                           newA.X += multiplier : newA.X;
                        newA.Y                     = PrefferredOrientation == PrefferredOrientation.Vertical ?
                                           newA.Y += multiplier : newA.Y;

                        newB = new Dimensions(newA.X, newA.Y);
                    }
                    //SameCol
                    else if (a.X == b.X)
                    {
                        newA.Y += multiplier;
                        newB.Y += multiplier;
                    }
                    //SameRow
                    else
                    {
                        newA.X += multiplier;
                        newB.X += multiplier;
                    }

                    newA.Limit(keytable.Dimensions);
                    newB.Limit(keytable.Dimensions);
                }

                output.Append(keytable[newA]);
                output.Append(keytable[newB]);
            }

            return(output.ToString());
        }
示例#7
0
 ///<inheritdoc/>
 public Rotor(Alphabet indexing, Alphabet wiring) : base(indexing, wiring)
 {
 }
示例#8
0
 /// <summary>
 /// The alphabet to be used, in the machine and by the builder when creating the rotors and stators.
 /// When not provided, the default <see cref="Alphabets.ASCII"/> is used.
 /// </summary>
 /// <param name="alphabet"></param>
 /// <returns></returns>
 public EnigmaMachineBuilder WithAlphabet(Alphabet alphabet)
 {
     _alphabet = alphabet;
     return(this);
 }
示例#9
0
        /// <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,
            });
        }
示例#10
0
 /// <summary>
 /// Creates a wheel from the specified indexing and wiring
 /// </summary>
 /// <param name="indexing">The index etchings</param>
 /// <param name="wiring">The scrambled of the indexing</param>
 public EnigmaWheel(string indexing, string wiring)
 {
     Indexing = new Alphabet(indexing);
     Wiring   = new Alphabet(wiring);
 }
示例#11
0
 /// <summary>
 /// Creates a wheel from the specified indexing and wiring
 /// </summary>
 /// <param name="indexing">The index etchings</param>
 /// <param name="wiring">The scrambled of the indexing</param>
 public EnigmaWheel(Alphabet indexing, Alphabet wiring)
 {
     Indexing = indexing;
     Wiring   = wiring;
 }