Advertisement
Guest User

Enigma.cs

a guest
Feb 12th, 2016
264
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.52 KB | None | 0 0
  1. namespace EnigmaCode
  2. {
  3.  
  4.     /**
  5.      * THE ROTOR CLASS
  6.      *
  7.      * Used to store rotor information, such as its cycle size, the number of turns it has made, and the internal alphabet order.
  8.      */
  9.     class Rotor
  10.     {
  11.  
  12.         /**
  13.          * THE CLASS PROPERTIES
  14.          */
  15.         private List<char> _In = new List<char>();
  16.         private List<char> _Out = new List<char>();
  17.  
  18.         private int cycle = 0;
  19.         private int turns = 1;
  20.  
  21.  
  22.         /**
  23.          * THE ACCESSORS
  24.          */
  25.         public List<char> In
  26.         {
  27.             get { return _In; }
  28.             set { _In = value; }
  29.         }
  30.  
  31.         public List<char> Out
  32.         {
  33.             get { return _Out; }
  34.             set { _Out = value; }
  35.         }
  36.  
  37.  
  38.         /**
  39.          * THE CONSTRUCTOR
  40.          */
  41.         public Rotor(int Rslot)
  42.         {
  43.             if (Rslot == 1)
  44.             {
  45.                 cycle = 1;
  46.             } else {
  47.                 Rslot -= 1;
  48.                 cycle = Convert.ToInt32(Math.Pow(28, Rslot));
  49.             }
  50.         }
  51.  
  52.  
  53.         /**
  54.          * THE PUBLIC METHODS
  55.          */
  56.  
  57.         /**
  58.          * Returns the number of turns. Only meant for debugging.
  59.          */
  60.         public int getT
  61.         {
  62.             get { return turns; }
  63.         }
  64.  
  65.         /**
  66.          * Returns the size of the rotor's cycle. Only meant for debugging.
  67.          */
  68.         public int getC
  69.         {
  70.             get { return cycle; }
  71.         }
  72.  
  73.         /**
  74.          * Turn the rotor.
  75.          *
  76.          * If the rotor has made its full cycle, reset the turn count.
  77.          */
  78.         public void Turn()
  79.         {
  80.             if(turns == cycle) {
  81.                 int last = _Out.Count() - 1;
  82.                 char chr = _Out[last];
  83.  
  84.                 Out.RemoveAt(last);
  85.                 Out.Insert(0, chr);
  86.  
  87.                 turns = 1;
  88.             } else {
  89.                 turns += 1;
  90.             }
  91.         }
  92.  
  93.     }
  94.  
  95.     class Switch
  96.     {
  97.  
  98.         private char from;
  99.         private char to;
  100.  
  101.  
  102.         public char F
  103.         {
  104.             get { return F; }
  105.         }
  106.  
  107.         public char T
  108.         {
  109.             get { return T; }
  110.         }
  111.  
  112.  
  113.         public Switch(char F, char T)
  114.         {
  115.             from = F;
  116.             to = T;
  117.         }
  118.  
  119.         public char Reverse(char C)
  120.         {
  121.             if (C != to)
  122.             {
  123.                 return C;
  124.             }
  125.             return from;
  126.         }
  127.  
  128.         public char Transform(char C)
  129.         {
  130.             if(C != from)
  131.             {
  132.                 return C;
  133.             }
  134.             return to;
  135.         }
  136.     }
  137.  
  138.     /**
  139.      * THE ENIGMA CLASS.
  140.      *
  141.      * Use this class to encrypt and decrypt phrases and sentences.
  142.      */
  143.     class Enigma
  144.     {
  145.  
  146.         /**
  147.          * THE CLASS PROPERTIES
  148.          */
  149.  
  150.         /**
  151.          * Class lists
  152.          */
  153.         private List<Rotor> Rotors = new List<Rotor>();
  154.         private List<Switch> Board = new List<Switch>();
  155.  
  156.         /**
  157.          * Class constants
  158.          */
  159.         private const string CHARS = "ABCDEFGHIJKLMNOPQRSTUWVXYZÖÄ1234567890";
  160.         private const int TOTALROTORS = 5;
  161.         private const int TOTALSWITCHES = 19;
  162.  
  163.         /**
  164.          * Class variables
  165.          */
  166.         private bool spaces = false;
  167.         private char whitespace;
  168.         private int Rset = 0;
  169.  
  170.  
  171.         /**
  172.          * PRIVATE METHODS
  173.          */
  174.        
  175.         private char Transform(char chr, bool R = false)
  176.         {
  177.             char output;
  178.  
  179.             for (int i = 0; i < Board.Count(); i++)
  180.             {
  181.                 if (R == true)
  182.                 {
  183.                     output = Board[i].Reverse(chr);
  184.                 } else {
  185.                     output = Board[i].Transform(chr);
  186.                 }
  187.  
  188.                 if (output != chr)
  189.                 {
  190.                     return output;
  191.                 }
  192.             }
  193.  
  194.             return chr;
  195.         }
  196.        
  197.         /**
  198.          * Decrypts one character.
  199.          *
  200.          * Validate each character by checking it against accepted alphabet before encrypting one character.
  201.          */
  202.         private char DecryptChar(char chr)
  203.         {
  204.             char output;
  205.  
  206.             if(Char.IsWhiteSpace(chr))
  207.             {
  208.                 return chr;
  209.             }
  210.  
  211.             if (!isValid(chr))
  212.             {
  213.                 throw new ArgumentException("Invalid character input.");
  214.             }
  215.  
  216.             output = chr;
  217.  
  218.             for (int i = Rotors.Count(); i > 0; i--)
  219.             {
  220.                 int e = i - 1;
  221.                 int alphalen = Rotors[e].In.Count();
  222.  
  223.                 for (int n = 0; n < alphalen; n++)
  224.                 {
  225.                     if (Rotors[e].Out[n] == output)
  226.                     {
  227.                         output = Rotors[e].In[n];
  228.                         break;
  229.                     }
  230.                 }
  231.             }
  232.  
  233.             if ((output == whitespace) && (spaces == true))
  234.             {
  235.                 return ' ';
  236.             }
  237.  
  238.             output = Transform(output, true);
  239.             return output;
  240.         }
  241.  
  242.         /**
  243.          * Encrypts one character.
  244.          *
  245.          * Validate each character by checking it against accepted alphabet before encrypting one character.
  246.          */
  247.         private char EncryptChar(char chr)
  248.         {
  249.             char output = Transform(chr);
  250.  
  251.             if (Char.IsWhiteSpace(chr))
  252.             {
  253.                 if (spaces == true)
  254.                 {  
  255.                     output = whitespace;
  256.                 } else {
  257.                     return ' ';
  258.                 }
  259.             }
  260.  
  261.             if (!isValid(output))
  262.             {
  263.                 throw new ArgumentException("Invalid character input.");
  264.             }
  265.  
  266.             for (int i = 0; i < Rotors.Count(); i++)
  267.             {
  268.                 int alphalen = Rotors[i].In.Count();
  269.  
  270.                 for (int n = 0; n < alphalen; n++)
  271.                 {
  272.                     if (Rotors[i].In[n] == output)
  273.                     {
  274.                         output = Rotors[i].Out[n];
  275.                         break;
  276.                     }
  277.                 }
  278.             }
  279.  
  280.             return output;
  281.         }
  282.  
  283.         /**
  284.          * Validates characters.
  285.          *
  286.          * Check the chr (=Character) against the list of valid characters.
  287.          * Return FALSE if chr is not a valid character.
  288.          */
  289.         private bool isValid(char chr)
  290.         {
  291.             bool valid = false;
  292.             List<char> alphabet = CHARS.ToList();
  293.  
  294.             for (int i = 0; i < alphabet.Count(); i++)
  295.             {
  296.                 if (alphabet[i] == chr)
  297.                 {
  298.                     valid = true;
  299.                 }
  300.             }
  301.  
  302.             return valid;
  303.         }
  304.  
  305.         /**
  306.          * Setup a rotor.
  307.          *
  308.          * Parses the rotor settings (name and initial position) from the passes parameter R (=Rotor). The information is validated
  309.          * and then the correct rotor is pulled and stored.
  310.          */
  311.         private void SetupRotor(double R)
  312.         {
  313.             /* Separate the rotor data into number and position */
  314.             var data = R.ToString().Split(',');
  315.             int Rnumber = Convert.ToInt32(data[0]);
  316.             int Rpos = 0; int Rcount = 0;
  317.  
  318.             /* Make sure rotor exists. */
  319.             if(Rnumber > TOTALROTORS)
  320.             {
  321.                 throw new ArgumentException("Invalid rotor number.");
  322.             }
  323.  
  324.             /* Pull and store the rotor alphabet. */
  325.             switch (Rnumber)
  326.             {
  327.                 case 1:
  328.                     Rotors.Add(new Rotor(1));
  329.                     Rotors[Rset].In = new RotorSetI().In;
  330.                     Rotors[Rset].Out = new RotorSetI().Out;
  331.                     Rset += 1;
  332.                     break;
  333.                 case 2:
  334.                     Rotors.Add(new Rotor(2));
  335.                     Rotors[Rset].In = new RotorSetII().In;
  336.                     Rotors[Rset].Out = new RotorSetII().Out;
  337.                     Rset += 1;
  338.                     break;
  339.                 case 3:
  340.                     Rotors.Add(new Rotor(3));
  341.                     Rotors[Rset].In = new RotorSetIII().In;
  342.                     Rotors[Rset].Out = new RotorSetIII().Out;
  343.                     Rset += 1;
  344.                     break;
  345.             }
  346.  
  347.             /* Turn the rotors to setup the initial settings. */
  348.             if (data.Count() > 1)
  349.             {
  350.                 Rpos = Convert.ToInt32(data[1]);
  351.  
  352.                 while (Rcount < Rpos)
  353.                 {
  354.                     TurnRotors();
  355.                     Rcount++;
  356.                 }
  357.             }
  358.            
  359.         }
  360.  
  361.         /**
  362.          * Turn the rotors.
  363.          *
  364.          * Loop through each rotor and call the Turn() method for the rotor object.
  365.          */
  366.         private void TurnRotors()
  367.         {
  368.             for(int i=0; i<Rotors.Count(); i++)
  369.             {
  370.                 Rotors[i].Turn();
  371.             }
  372.         }
  373.  
  374.  
  375.         /**
  376.          * CONSTRUCTORS
  377.          */
  378.         public Enigma(double RI)
  379.         {
  380.             SetupRotor(RI);
  381.         }
  382.  
  383.         public Enigma(double RI, double RII)
  384.         {
  385.             SetupRotor(RI);
  386.             SetupRotor(RII);
  387.         }
  388.  
  389.         public Enigma(double RI, double RII, double RIII)
  390.         {
  391.             SetupRotor(RI);
  392.             SetupRotor(RII);
  393.             SetupRotor(RIII);
  394.         }
  395.  
  396.  
  397.         /**
  398.          * PUBLIC METHODS
  399.          */
  400.  
  401.         /**
  402.          * Adds a character switch.
  403.          *
  404.          * Character pairs are added, which will be switched during the encryption process.
  405.          */
  406.         public void AddSwitch(char F, char T)
  407.         {
  408.             if (Board.Count() < TOTALSWITCHES)
  409.             {
  410.                 Switch Switch = new Switch(F, T);
  411.                 Board.Add(Switch);
  412.             } else {
  413.                 throw new ArgumentException("Too many switches.");
  414.             }
  415.         }
  416.  
  417.         /**
  418.          * Begins the decryption process.
  419.          *
  420.          * To avoid repeating identical code, Decrypt() only serves as a front to Encrypt().
  421.          */
  422.         public string Decrypt(string P)
  423.         {
  424.             string output = "";
  425.  
  426.             output = Encrypt(P, true);
  427.             return output;
  428.         }
  429.  
  430.         /**
  431.          * Begins the encryption process.
  432.          *
  433.          * Breakdown the P (=Phrase) into a list of characters; encrypt one character (by calling EncryptChar()) at a time and
  434.          * turn rotors after each character.
  435.          */
  436.         public string Encrypt(string P, bool D = false)
  437.         {
  438.             List<char> phrase = P.ToList();
  439.             string output = "";
  440.  
  441.             for(int i=0; i<phrase.Count(); i++)
  442.             {
  443.                 if (D == true)
  444.                 {
  445.                     output += DecryptChar(phrase[i]);
  446.                 } else {
  447.                     output += EncryptChar(phrase[i]);
  448.                 }
  449.  
  450.                 TurnRotors();
  451.             }
  452.  
  453.             return output;
  454.         }
  455.  
  456.         public bool IsWsEnabled()
  457.         {
  458.             return spaces;
  459.         }
  460.  
  461.         public void DisableWhiteSpaces()
  462.         {
  463.             spaces = false;
  464.         }
  465.  
  466.         public void SetWhiteSpace(char W)
  467.         {
  468.             if(!isValid(W))
  469.             {
  470.                 throw new ArgumentException("Invalid character input.");
  471.             }
  472.  
  473.             whitespace = W;
  474.             spaces = true;
  475.         }
  476.     }
  477.  
  478. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement