Click here to Skip to main content
15,881,794 members
Articles / Desktop Programming / Windows Forms

Enigma emulator in C#

Rate me:
Please Sign up or sign in to vote.
4.71/5 (22 votes)
29 Apr 2011CPOL4 min read 205.3K   6.5K   51   37
This article shows the inner workings of the German Enigma machine used during the WWII, translated to C#.

Enigma emulator main image

Enigma emulator rotor configuration

Introduction

This article shows how to implement an Enigma like cryptography using C#. This kind of cryptography system was used until the 70's. The most famous use of it was by the German army during the WWII. The breaking of this code led the allies to victory. This cryptography method can still be secure enough for use in non critical systems. If the Germans would have used the method with care, maybe the allies would not have discovered their secrets.

Background

The reader might be interested in some general information about Enigma. These links could help you:

Using the code

This code is a complete program that shows the inner workings of such a machine. If the user wants to understand more about the Enigma machine, then he/she would need to Google for more information. This code shows how simple it is to emulate such complicate wirings as those of the Enigma machine, using a modern programming language.

The machine has at least three rotors, each one having the alphabet written on it. The rotors has a visible part which consists of the alphabet and a part that has other letters which are linked to the first one by wires. The three rotors are arranged one after the other from right to left. The rotor is not static.

This kind of machine was a combination of electrical and mechanical cryptography system. Basically, when the user of the machine pressed a key, the current would go to the first rotor to the letter corresponding to that key (let's say 'A'). The wirings of the wheel would lead to an output letter from the first rotor with a different value, let's say 'D', this impulse would then go to the second rotor, and the same thing would happen there, and in the third rotor. From there, the impulse would go to a last wheel - that is named the 'reflector'. This wheel (rotor) is the only non rotating wheel. The impulse would go to this wheel and from here it would return to the third rotor, and make its way backwards. From the first rotor, the current would illuminate a LED under a panel. This would be the encrypted letter.

This is not all. At each key press, the first rotor would rotate with one position so that the output letter would not be the same when you press the same key twice. The second rotor would rotate one position once at every 28 rotations of the first rotor, and the third one once every 28 rotations of the second rotor. As I've said earlier, the reflector is the only static rotor. On some models, the second and third rotor would rotate more than once at every 28 rotations of the previous rotor.

To decrypt the data, you just had to set the rotors at the exact initial position as the rotors on the machine that produced that output and then type in the encrypted data.

There were several rotors and they could be changed. To complicate things even more, the military version had a front panel with letters were you could interconnect two letters so that each time a letter would occur, it would be replaced with the other one. To show this kind of complicated inner workings, the following C# code would suffice:

C#
//encrypt the data in the upper text box, and put the result in the lower one
//this code is taking the data in one text box 
//and puts the crypted/decrypted result
//in another one.
void Button1Click(object sender, System.EventArgs e)
{
   char[] chIn = txtInit.Text.ToUpper().ToCharArray();
   txtFinal.Text = "";
   for(int i=0;i<chIn.Length;i++){
      //we only use the upper letters
      if(chIn[i]>=65 && chIn[i]<=90){
         rr.Move();
         rr.PutDataIn(chIn[i]);
         txtFinal.AppendText(""+rr.GetDataOut());
      }
   }
}

You can see that we only use the upper letters. That's because the existence of punctuation and spaces would help in the decryption of the message.

I've also created a rotor class which practically represents one rotor of the enigma machine. In this class, we have the methods Move which moves the rotor one position and the PutDataIn which emulates the sending of the electric signal to the first rotor. As you can see, we only send the data to the first rotor, which will send the data further down the chain.

Here is the code for this class:

C#
using System;
using System.Text;
using System.Windows.Forms;

namespace Enigma
{

    public class Rotor
    {
        private string layout;
        private byte offset;
        private Rotor previous, next;
        private Label lbl;
        private char cIn = '\0', notchPos;

        public Rotor(string layout,Label lbl,char notchPos)
        {
            this.layout = layout;
            this.previous = previous;
            this.next = next;
            this.lbl = lbl;
            this.notchPos = notchPos;
            offset = 0;

        }

        public string GetLayout(){
            return layout;
        }

        public void SetNextRotor(Rotor next){
            this.next = next;
        }
        public void SetPreviousRotor(Rotor previous){
            this.previous = previous;
        }

        public char GetInverseCharAt(string ch){
            int pos = layout.IndexOf(ch);

            if(offset>pos){
                pos = 26 - (offset-pos);
            }else{
                pos = pos - offset;
            }

            if(previous!=null){
                pos = (pos+previous.GetOffset())%26;
            }

            return (char)(65+pos);
        }

        public int GetOffset(){
            return offset;
        }

        public char GetNotchPos(){
            return notchPos;
        }

        public void ResetOffset(){
            offset = 0;
        }

        public bool HasNext(){
            return next!=null;
        }

        public bool HasPrevious(){
            return previous!=null;
        }

        public void Move(){
            if(next==null){
                return;
            }
            offset++;
            if(offset==26){
                offset = 0;
            }

            if(next!=null && (offset+65) == ((notchPos-65)%26)+66){
                next.Move();
            }
            lbl.Text = ""+((char)(65+offset));
        }

        public void MoveBack(){
            if(offset==0){
                offset = 26;
            }
            offset--;

            lbl.Text = ""+((char)(65+offset));
        }

        public void PutDataIn(char s){
            cIn = s;
            char c = s;
            c = (char)(((c - 65) + offset) % 26 + 65);

            if(next!=null){
                c = layout.Substring((c-65),1).ToCharArray()[0];
                if((((c-65)+(-offset))%26 + 65)>=65){
                    c = (char)(((c-65)+(-offset))%26 + 65);
                }else{
                    c = (char)(((c-65)+(26+(-offset)))%26 + 65);
                }
                next.PutDataIn(c);

            }
        }

        public char GetDataOut(){
            char c = '\0';

            if(next!=null){
                c = next.GetDataOut();
                c = GetInverseCharAt(""+c);
            }else{ //only in the reflector case
                c = layout.Substring((cIn-65),1).ToCharArray()[0];
                c = (char)(((c - 65) + previous.offset)%26+65);

            }

            return c;
        }

    }
}

Points of Interest

Although it seems peculiar, the older the cryptographic algorithm, the safer it is. This is because it means that people have tested it and they did not found any way in. Maybe in a later article, I will show you how to implement an instant messenger that uses this cryptography technique.

History

  • Apr 29, 2011: Updated source code.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Romania Romania
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionhow to replace its rotor? Pin
Member 1347220030-Dec-17 17:32
Member 1347220030-Dec-17 17:32 
QuestionThanks ! Pin
Member 131853587-May-17 14:42
Member 131853587-May-17 14:42 
QuestionNullReferenceException Pin
Member 1122029810-Aug-15 0:27
professionalMember 1122029810-Aug-15 0:27 
NewsArduino Enigma Machine Simulator Pin
ArduinoEnigma24-Nov-14 16:43
ArduinoEnigma24-Nov-14 16:43 
QuestionThis is good, but there's one step missing Pin
warny9-Jun-14 23:13
warny9-Jun-14 23:13 
GeneralMy vote of 3 Pin
KatsuneShinsengumi16-Jan-14 2:55
KatsuneShinsengumi16-Jan-14 2:55 
Questionyou need more of this subject and other programs of this Enigma Machine Pin
Member 963960218-Dec-13 22:35
Member 963960218-Dec-13 22:35 
Bugvery small "bug" in the Settings.cs [modified] Pin
fred edison24-Aug-11 2:46
fred edison24-Aug-11 2:46 
GeneralQuick note on Enigma! Pin
egomezb29-Apr-11 13:14
egomezb29-Apr-11 13:14 
GeneralRe: Quick note on Enigma! [modified] Pin
Selvin1-May-11 22:19
Selvin1-May-11 22:19 
Generalsmall bug with rotor V [modified] Pin
fred edison19-Dec-08 7:07
fred edison19-Dec-08 7:07 
GeneralRe: small bug with rotor V Pin
fred edison19-Dec-08 8:55
fred edison19-Dec-08 8:55 
GeneralRe: small bug with rotor V Pin
adi_clepcea28-Apr-11 21:33
adi_clepcea28-Apr-11 21:33 
GeneralThere is an error in the rotor rotation algorithm Pin
Member 149490626-Sep-08 3:43
Member 149490626-Sep-08 3:43 
GeneralEngima coded message Pin
rah200618-Aug-08 8:24
rah200618-Aug-08 8:24 
GeneralRe: Engima coded message Pin
rah200620-Aug-08 3:27
rah200620-Aug-08 3:27 
GeneralI used your rotor class in my program to brute force Enigma Pin
Didier Stevens28-Dec-06 1:37
Didier Stevens28-Dec-06 1:37 
GeneralRe: I used your rotor class in my program to brute force Enigma Pin
adi_clepcea28-Dec-06 1:52
adi_clepcea28-Dec-06 1:52 
GeneralRe: I used your rotor class in my program to brute force Enigma Pin
Member 1347220031-Dec-17 3:40
Member 1347220031-Dec-17 3:40 
GeneralRotors' Table Pin
mrhadiahmadi6-Aug-05 1:11
mrhadiahmadi6-Aug-05 1:11 
GeneralRe: Rotors' Table Pin
adi_clepcea6-Aug-05 7:17
adi_clepcea6-Aug-05 7:17 
GeneralRe: Rotors' Table Pin
Anonymous8-Aug-05 1:18
Anonymous8-Aug-05 1:18 
GeneralRe: Rotors' Table Pin
adi_clepcea8-Aug-05 17:43
adi_clepcea8-Aug-05 17:43 
Well,
The germans had the five rotors (initially) (from which they could choose three to use. The five rotors had the same configuration for all the machines.
When they put the rotors in the machine, they could choose any combination and order of the rotors. This could give them lots of mapping possibilities.
The was no rotor order and starting possitions. The only thing was that they had to transmit the exact order of the rotors to the person deciphering the message.
I don't know if you can create custom rotors (different letter order - mapping) and get the same results as with the ones used by the germans.
This could be a good exercise to try.
(The advanced versions of enigma could use more rotors,but they were however limited by the fact that they had to be able to cript messages that could be decripted by older machines.)
Whenever you set a different starting possition for any rotor you have a different mapping.
The explication below is only valid for the version of enigma I've presented in my article.
The mapping only depends on the order of the letters on the rotor, the wirings inside the rotor and between rotors(offset) and rotor starting possitions.
The wirrings inside the rotors are fixed. You only had exact mappings you could use (as far as I know). The wirrings between rotors depended on the possition of each rotor, but you could not change the offset of the wirring.
In the links I provided you also have a calculation of the possibilities of configuration
HTH
Adi
GeneralStrange problem Pin
ROCKISDEAD4-May-05 23:15
ROCKISDEAD4-May-05 23:15 
GeneralRe: Strange problem Pin
adi_clepcea8-May-05 19:21
adi_clepcea8-May-05 19:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.