昨天和一个朋友又看了一遍模拟游戏,晚上回到家里闲的无聊,就写了一个简单的enigma模拟器。主要熟悉了他的加密算法以及解密设置。总的来说并不复杂,今天早上还做了一下UI,虽然没有做反射器,但是觉得基本上也是一个挺好玩的东西了,所以贴出来~
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
namespace ENIGMA
{
public class EnigmaSystem
{
//定义转子
public int[,] rotatorsPos;
public int[,] currentPos;
public Dictionary<char, int> input;
public Dictionary<int, char> output;
//构造器
public EnigmaSystem()
{
}
//初始化转子
public void Load(string path)
{
//初始化绑定输入输出字典
#region 初始化绑定
input =new Dictionary<char,int>(26);
for (int i= 65; i<=90; i++)
{
input.Add((char)i, i-64);
}
output = new Dictionary<int, char>(26);
for (int i = 65; i <= 90; i++)
{
output.Add( i - 64,(char)i);
}
#endregion
//初始化转子
rotatorsPos = new int [3,26]; //3*26
currentPos = new int [3, 26];
//从外部txt读入rotators固化线路的位置信息矩阵
TxtToRotators(path);
}
//设置转子
public void Setting(int rotator1=0, int rotator2=0, int rotator3=0)
{
int setting = rotator1 + 26 * rotator2 + 26 * 26 * rotator3;
currentPos = TurningRotator(setting);
}
//将Rotators数据写入到txt文件中
public void RotatorsToTxt(string path ="D:\\RotatorsData.txt" )
{
StreamWriter sw = new StreamWriter(path);
for (int i = 0; i < rotatorsPos.GetLength(0); i++)
{
for (int j = 1; j <= rotatorsPos.GetLength(1); j++)
{
sw.Write(rotatorsPos[i, j]);
sw.Write(' ');
}
sw.WriteLine();
}
sw.Close();
sw.Dispose();
}
//从txt文件中读取Rotators Position数据
public void TxtToRotators(string path ="D:\\RotatorsData.txt")
{
//txt数组:
//13 13 13 35
//25 25 35 31
StreamReader reader = new StreamReader(path);
int i = 0;
while (!reader.EndOfStream)
{
var line = reader.ReadLine().Split(new[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
for (int j= 0; j < line.Length; j++)
{
rotatorsPos[i, j] = Convert.ToInt32(line[j]);
}
i++;
}
currentPos = (int[,])rotatorsPos.Clone();
}
//转动转子得到位置
public int[,] TurningRotator(int PosChange) //Pos 只能为正
{
int[,] newRotatorsPos = new int [3,26]; //3*26 ;
int[] rotatorchange = new int [3];
int i,j;
int higherDigital;
for (i = 0; i < 3; i++)
{
higherDigital= PosChange /(int)Math.Pow(26,i);
rotatorchange[i]=higherDigital % 26;
j=0;
while (j<26)
{
if (j< 26-rotatorchange[i])
newRotatorsPos[i,j]=currentPos[i,j+rotatorchange[i]];
else
newRotatorsPos[i, j] = currentPos[i, j -(26 - rotatorchange[i])];
j++;
}
}
return newRotatorsPos;
}
//打印转子位置信息
public void PrintRotators()
{
for (int i = 0; i < rotatorsPos.GetLength(0); i++)
{
Console.Write("Rotator {0}: \t",i);
for (int j = 0; j < rotatorsPos.GetLength(1); j++)
{
Console.Write("{0}\t",rotatorsPos[i,j]);
}
Console.WriteLine();
}
}
public void PrintRotators(int[,] newRotatorsPos)
{
for (int i = 0; i < 3; i++)
{
Console.Write("Rotator {0}: \t", i);
for (int j = 0; j < 26; j++)
{
Console.Write("{0}\t", newRotatorsPos[i, j]);
}
Console.WriteLine();
}
}
//加密
public char Encrypt(char ch)
{
//输出对应的密码字符
char result = output[currentPos[2, currentPos[1, currentPos[0, input[ch] - 1]-1] - 1]];
//打完一个字符,转子转一次
currentPos = TurningRotator(1);
//返回结果
return result;
}
public string Encrypt(string ss)
{
char[] chs = ss.ToCharArray();
for (int i = 0; i < chs.Length; i++)
{
chs[i] = Encrypt(chs[i]);
}
return new string(chs);
}
//解密
public int[] OriginPositionSetting(string cipher)
{
char[] chs = cipher.ToCharArray();
int[] positionSetting = new int[3] {0,0,0};
for (int i = 0; i < 26; i++)
{
for (int j = 0; j < 26; j++)
{
for (int k = 0; k < 26; k++)
{
currentPos =(int[,]) rotatorsPos.Clone();
currentPos = TurningRotator(cipher.Length-10+i*26*26+j*26+k);
if (Encrypt("HEILHITLER")==cipher.Substring(cipher.Length - 10) )
{
positionSetting[0] = k;
positionSetting[1] = j;
positionSetting[2] = i;
break;
}
}
}
}
return positionSetting;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
namespace ENIGMA
{
class Program
{
static void Main(string[] args)
{
EnigmaSystem ES = new EnigmaSystem();
ES.Load(@"C:\Users\Hui WU\Desktop\工作簿1.txt");
Console.WriteLine("初始转子信息:");
ES.PrintRotators();
//调用user interface
Application.EnableVisualStyles();
EnigmaUI ui = new EnigmaUI(ES);
Application.Run(ui);
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ENIGMA
{
public partial class EnigmaUI : Form
{
EnigmaSystem ES;
public EnigmaUI(EnigmaSystem ES)
{
InitializeComponent();
this.ES = ES;
}
private void EnigmaUI_Load(object sender, EventArgs e)
{
}
private void btnA_Click(object sender, EventArgs e)
{
tbxClear.Text += "A";
}
private void btnQ_Click(object sender, EventArgs e)
{
tbxClear.Text += "Q";
}
private void btnEncoding_Click(object sender, EventArgs e)
{
ES.Setting(trackBar1.Value,trackBar2.Value,trackBar3.Value);
tbxCipher.Text = ES.Encrypt(tbxClear.Text);
}
private void btnW_Click(object sender, EventArgs e)
{
tbxClear.Text += "W";
}
private void btnE_Click(object sender, EventArgs e)
{
tbxClear.Text += "E";
}
private void btnR_Click(object sender, EventArgs e)
{
tbxClear.Text += "R";
}
private void btnT_Click(object sender, EventArgs e)
{
tbxClear.Text += "T";
}
private void btnZ_Click(object sender, EventArgs e)
{
tbxClear.Text += "Z";
}
private void btnU_Click(object sender, EventArgs e)
{
tbxClear.Text += "U";
}
private void btnI_Click(object sender, EventArgs e)
{
tbxClear.Text += "I";
}
private void btnO_Click(object sender, EventArgs e)
{
tbxClear.Text += "O";
}
private void btnS_Click(object sender, EventArgs e)
{
tbxClear.Text += "S";
}
private void btnD_Click(object sender, EventArgs e)
{
tbxClear.Text += "D";
}
private void btnF_Click(object sender, EventArgs e)
{
tbxClear.Text += "F";
}
private void btnG_Click(object sender, EventArgs e)
{
tbxClear.Text += "G";
}
private void btnH_Click(object sender, EventArgs e)
{
tbxClear.Text += "H";
}
private void btnJ_Click(object sender, EventArgs e)
{
tbxClear.Text += "J";
}
private void btnK_Click(object sender, EventArgs e)
{
tbxClear.Text += "K";
}
private void btnP_Click(object sender, EventArgs e)
{
tbxClear.Text += "P";
}
private void btnY_Click(object sender, EventArgs e)
{
tbxClear.Text += "Y";
}
private void btnX_Click(object sender, EventArgs e)
{
tbxClear.Text += "X";
}
private void btnC_Click(object sender, EventArgs e)
{
tbxClear.Text += "C";
}
private void btnV_Click(object sender, EventArgs e)
{
tbxClear.Text += "V";
}
private void btnB_Click(object sender, EventArgs e)
{
tbxClear.Text += "B";
}
private void btnN_Click(object sender, EventArgs e)
{
tbxClear.Text += "N";
}
private void btnM_Click(object sender, EventArgs e)
{
tbxClear.Text += "M";
}
private void btnL_Click(object sender, EventArgs e)
{
tbxClear.Text += "L";
}
private void btnDecoding_Click(object sender, EventArgs e)
{
int[] positionSetting=ES.OriginPositionSetting(tbxCipher.Text);
trackBar1.Value = positionSetting[0];
trackBar2.Value = positionSetting[1];
trackBar3.Value = positionSetting[2];
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
lblR1.Text = trackBar1.Value.ToString();
}
private void trackBar2_Scroll(object sender, EventArgs e)
{
lblR2.Text = trackBar2.Value.ToString();
}
private void trackBar3_Scroll(object sender, EventArgs e)
{
lblR3.Text = trackBar3.Value.ToString();
}
private void trackBar1_ValueChanged(object sender, EventArgs e)
{
lblR1.Text = trackBar1.Value.ToString();
}
private void trackBar2_ValueChanged(object sender, EventArgs e)
{
lblR2.Text = trackBar2.Value.ToString();
}
private void trackBar3_ValueChanged(object sender, EventArgs e)
{
lblR3.Text = trackBar3.Value.ToString();
}
}
}