Created
January 10, 2017 20:20
-
-
Save jimbojetset/3ff02650899773ce3700213cc7a52689 to your computer and use it in GitHub Desktop.
Enigma Emulator c#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Text; | |
using System.Diagnostics; | |
namespace Enigma | |
{ | |
class EnigmaMachine | |
{ | |
private const string _alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
private static Tuple<string, int, int> _rotor_Blank = new Tuple<string, int, int>("ABCDEFGHIJKLMNOPQRSTUVWXYZ", -99, -99); | |
private static Tuple<string, int, int> _rotor_I = new Tuple<string, int, int>("EKMFLGDQVZNTOWYHXUSPAIBRCJ", 16, -99); | |
private static Tuple<string, int, int> _rotor_II = new Tuple<string, int, int>("AJDKSIRUXBLHWTMCQGZNPYFVOE", 4, -99); | |
private static Tuple<string, int, int> _rotor_III = new Tuple<string, int, int>("BDFHJLCPRTXVZNYEIWGAKMUSQO", 21, -99); | |
private static Tuple<string, int, int> _rotor_IV = new Tuple<string, int, int>("ESOVPZJAYQUIRHXLNFTGKDCMWB", 9, -99); | |
private static Tuple<string, int, int> _rotor_V = new Tuple<string, int, int>("VZBRGITYUPSDNHLXAWMJQOFECK", 25, -99); | |
private static Tuple<string, int, int> _rotor_VI = new Tuple<string, int, int>("JPGVOUMFYQBENHZRDKASXLICTW", 25, 12); | |
private static Tuple<string, int, int> _rotor_VII = new Tuple<string, int, int>("NZJHGRCXMYSWBOUFAIVLPEKQDT", 25, 12); | |
private static Tuple<string, int, int> _rotor_VIII = new Tuple<string, int, int>("FKQHTLXOCBJSPDZRAMEWNIUYGV", 25, 12); | |
private static Tuple<string, int, int> _rotor_b = new Tuple<string, int, int>("LEYJVCNIXWPBQMDRTAKZGFUHOS", -99, -99); | |
private static Tuple<string, int, int> _rotor_g = new Tuple<string, int, int>("FSOKANUERHMBTIYCWLQPZXVGJD", -99, -99); | |
private static string _reflector_Blank = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
private static string _reflector_A = "EJMZALYXVBWFCRQUONTSPIKHGD"; | |
private static string _reflector_B = "YRUHQSLDPXNGOKMIEBFZCWVJAT"; | |
private static string _reflector_C = "FVPJIAOYEDRZXWGCTKUQSBNMHL"; | |
private static string _reflector_b = "ENKQAUYWJICOPBLMDXZVFTHRGS"; | |
private static string _reflector_c = "RDOBJNTKVEHMLFCWZAXGYIPSUQ"; | |
private static Rotor _rotor0; | |
private static Rotor _rotor1; | |
private static Rotor _rotor2; | |
private static Rotor _rotor3; | |
private static Reflector _reflector; | |
private static Plugboard _plugboard; | |
private static bool _readyToDecode = false; | |
public bool SetupEnigmaMachine(string setupValues) | |
{ | |
try | |
{ | |
string[] value = setupValues.Split(':'); | |
if (value.Length == 6) | |
{ | |
char reflector = value[0][0]; | |
string reel = value[1]; | |
string ring = value[2].ToUpper(); | |
string pstn = value[3].ToUpper(); | |
string plugboard = value[4].ToUpper(); | |
_reflector = Create_Reflector(reflector); | |
_rotor0 = Create_Rotor(reel[0], ring[0], pstn[0]); | |
_rotor1 = Create_Rotor(reel[1], ring[1], pstn[1]); | |
_rotor2 = Create_Rotor(reel[2], ring[2], pstn[2]); | |
_rotor3 = Create_Rotor(reel[3], ring[3], pstn[3]); | |
_plugboard = Create_Plugboard(plugboard); | |
_readyToDecode = true; | |
return true; | |
} | |
else throw new Exception(); | |
} | |
catch | |
{ | |
_readyToDecode = false; | |
return false; | |
} | |
} | |
public string Transpose_CipherText(string cipherText) | |
{ | |
if (_readyToDecode && cipherText.Length > 0) | |
{ | |
StringBuilder plainText = new StringBuilder(); | |
foreach (char keyValue in cipherText) | |
if (keyValue == ' ') | |
plainText.Append(' '); | |
else | |
{ | |
int lampValue = KeyPress(_alpha.IndexOf(keyValue)); | |
plainText.Append(_alpha[lampValue]); | |
} | |
return plainText.ToString(); | |
} | |
return Help; | |
} | |
public static int KeyPress(int keyValue) | |
{ | |
if (_readyToDecode) | |
{ | |
RotateTheRotors(); | |
int lampValue = GetLampValue(keyValue); | |
return lampValue; | |
} | |
return -99; | |
} | |
private static int GetLampValue(int keyValue) | |
{ | |
int val = _plugboard.GetIndex(keyValue); | |
val = _rotor3.Transpose(val, Rotor.Path.Fwd); | |
val = _rotor2.Transpose(val, Rotor.Path.Fwd); | |
val = _rotor1.Transpose(val, Rotor.Path.Fwd); | |
val = _rotor0.Transpose(val, Rotor.Path.Fwd); | |
val = _reflector.GetIndex(val); | |
val = _rotor0.Transpose(val, Rotor.Path.Rev); | |
val = _rotor1.Transpose(val, Rotor.Path.Rev); | |
val = _rotor2.Transpose(val, Rotor.Path.Rev); | |
val = _rotor3.Transpose(val, Rotor.Path.Rev); | |
int lampValue = _plugboard.GetIndex(val); | |
return lampValue; | |
} | |
private static void RotateTheRotors() | |
{ | |
if (_rotor2.IsNotched) | |
{ | |
_rotor1.Rotate(); | |
_rotor2.Rotate(); | |
} | |
else if (_rotor3.IsNotched) | |
_rotor2.Rotate(); | |
_rotor3.Rotate(); | |
} | |
private static Reflector Create_Reflector(char reflector) | |
{ | |
switch (reflector) | |
{ | |
case '-': | |
return new Reflector(_reflector_Blank); | |
case 'A': | |
return new Reflector(_reflector_A); | |
case 'B': | |
return new Reflector(_reflector_B); | |
case 'C': | |
return new Reflector(_reflector_C); | |
case 'b': | |
return new Reflector(_reflector_b); | |
case 'c': | |
return new Reflector(_reflector_c); | |
} | |
throw new Exception(); | |
} | |
private static Rotor Create_Rotor(char reel, char ring, char pstn) | |
{ | |
switch (reel) | |
{ | |
case '-': | |
return new Rotor(_rotor_Blank, 0, 0); | |
case '1': | |
return new Rotor(_rotor_I, _alpha.IndexOf(ring), _alpha.IndexOf(pstn)); | |
case '2': | |
return new Rotor(_rotor_II, _alpha.IndexOf(ring), _alpha.IndexOf(pstn)); | |
case '3': | |
return new Rotor(_rotor_III, _alpha.IndexOf(ring), _alpha.IndexOf(pstn)); | |
case '4': | |
return new Rotor(_rotor_IV, _alpha.IndexOf(ring), _alpha.IndexOf(pstn)); | |
case '5': | |
return new Rotor(_rotor_V, _alpha.IndexOf(ring), _alpha.IndexOf(pstn)); | |
case '6': | |
return new Rotor(_rotor_VI, _alpha.IndexOf(ring), _alpha.IndexOf(pstn)); | |
case '7': | |
return new Rotor(_rotor_VII, _alpha.IndexOf(ring), _alpha.IndexOf(pstn)); | |
case '8': | |
return new Rotor(_rotor_VIII, _alpha.IndexOf(ring), _alpha.IndexOf(pstn)); | |
case 'b': | |
return new Rotor(_rotor_b, _alpha.IndexOf(ring), _alpha.IndexOf(pstn)); | |
case 'g': | |
return new Rotor(_rotor_g, _alpha.IndexOf(ring), _alpha.IndexOf(pstn)); | |
} | |
throw new Exception(); | |
} | |
private static Plugboard Create_Plugboard(string plugboardLinks) | |
{ | |
_plugboard = new Plugboard(); | |
string[] links = plugboardLinks.Split('-'); | |
if (plugboardLinks.Length > 0) | |
foreach (string link in links) | |
_plugboard.Swap(_alpha.IndexOf(link[0]), _alpha.IndexOf(link[1])); | |
return _plugboard; | |
} | |
public string Help | |
{ | |
get | |
{ | |
StringBuilder errorMessage = new StringBuilder(); | |
errorMessage.Append("Invalid arguments supplied.\n\n"); | |
errorMessage.Append("Example 1 - B:-123:-ABC:-XYZ:AB-CD-EF:BLELDVPPFW\n(3 Rotor M3 Wehrmacht Enigma with plug settings)\n\n"); | |
errorMessage.Append("Example 1 - B:-123:-ABC:-XYZ::SLFLPVPVEW\n(3 Rotor M3 Wehrmacht Enigma with no plug settings)\n\n"); | |
errorMessage.Append("Example 2 - B:b123:AABC:AXYZ::\"NKIK UJQA RR\"\n(4 Rotor M4 Navy Enigma)\n\n"); | |
errorMessage.Append(" Reeflector - B (A B C b c)\n"); | |
errorMessage.Append(" Reels(left to right) - 123 ( 1 2 3 4 5 6 7 8 b g)\n"); | |
errorMessage.Append(" Ring Position(left to right) - ABC\n"); | |
errorMessage.Append(" Start Position(left to right) - XYZ\n"); | |
errorMessage.Append(" Plugboard Wiring - AB-CD-EF (optional)\n"); | |
errorMessage.Append(" Ciphertext can be entered as CIPHERTEXT or \"CIPH ERTE TX\""); | |
return errorMessage.ToString(); | |
} | |
} | |
} | |
class Rotor | |
{ | |
private string _pattern; | |
private string _alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
private int _notch1; | |
private int _notch2; | |
private int _reelPosition = 0; | |
private int _rsl = 0; | |
public enum Path { Fwd, Rev }; | |
public Rotor(Tuple<string, int, int> rotor, int ringPos, int startPos) | |
{ | |
_pattern = rotor.Item1; | |
_notch1 = rotor.Item2; | |
_notch2 = rotor.Item3; | |
_reelPosition = startPos; | |
_rsl = ringPos; | |
} | |
public bool IsNotched | |
{ | |
get { return (_reelPosition == _notch1 || _reelPosition == _notch2); } | |
} | |
public void Rotate() | |
{ | |
_reelPosition = (_reelPosition + 1) % 26; | |
} | |
public int Transpose(int x, Path dir) | |
{ | |
x = (x + _reelPosition - _rsl + 26) % 26; | |
int t = GetIndex(x, dir) - _reelPosition + _rsl + 26; | |
return t % 26; | |
} | |
private int GetIndex(int x, Path dir) | |
{ | |
if (dir == Path.Fwd) | |
return _alpha.IndexOf(_pattern[x]); | |
else | |
return _pattern.IndexOf(_alpha[x]); | |
} | |
} | |
class Reflector | |
{ | |
private string _alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
private string _pattern; | |
public Reflector(string pattern) | |
{ | |
_pattern = pattern; | |
} | |
public int GetIndex(int x) | |
{ | |
return _pattern.IndexOf(_alpha[x]); | |
} | |
} | |
class Plugboard | |
{ | |
public string _alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
public string _pattern = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
public void Swap(int a, int b) | |
{ | |
if (a != b && _alpha[a] == _pattern[a] && _alpha[b] == _pattern[b]) | |
_pattern = _pattern.Replace(_alpha[a], '~').Replace(_pattern[b], _alpha[a]).Replace('~', _pattern[b]); | |
else throw new Exception(); | |
} | |
public int GetIndex(int x) | |
{ | |
return _pattern.IndexOf(_alpha[x]); | |
} | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using Enigma; | |
class Program | |
{ | |
private static EnigmaMachine enigma = new EnigmaMachine(); | |
static void Main(string[] args) | |
{ | |
if (args.Length == 1) | |
{ | |
string[] values = args[0].Split(':'); | |
if (values.Length == 6) | |
{ | |
string cipherText = values[5].ToUpper(); | |
if (enigma.SetupEnigmaMachine(args[0])) | |
{ | |
Console.WriteLine(" IN: " + cipherText); | |
Console.WriteLine(""); | |
Console.WriteLine("OUT: " + enigma.Transpose_CipherText(cipherText)); | |
} | |
else | |
Console.WriteLine(enigma.Help); | |
} | |
else | |
Console.WriteLine(enigma.Help); | |
} | |
else | |
Console.WriteLine(enigma.Help); | |
Console.WriteLine("\nPress ANY Key To Exit"); | |
Console.ReadKey(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment