Почему шифрация/дешифрация происходит неверно?
Код запускается и работает, однако шифрация и дешифрация происходят некорректно. Для запуска кода требуется добавить класс ротора. Код основного файла представлен ниже класса ротора. Проблема заключается в том, что сообщение возможно зашифровать, однако не получается дешифровать(получить исходное). (Уточнение, после шифрации требуется перезапустить программу и вставить шифртекст, после чего пробовать дешифровать.)
Класс ротора
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApp2
{
public class Rotor_Ru
{
//Описание переменных класса
private string layout;
private byte offset;
private Rotor_Ru previous, next;
private char cIn = '\0', notchPos;
//Конструктор класса ротора
public Rotor_Ru(string layout, char notchPos)
{
//Присвоение внутренним переменным класса значений
this.layout = layout;
this.previous = previous;
this.next = next;
this.notchPos = notchPos;
offset = 0;
}
//Получение раскладки
public string GetLayout()
{
return layout;
}
//Установить следующий ротор
public void SetNextRotor(Rotor_Ru next)
{
this.next = next;
}
//Установить предыдущий ротор
public void SetPreviousRotor(Rotor_Ru previous)
{
this.previous = previous;
}
//Получить инверсированный символ
public char GetInverseCharAt(string ch)
{
int pos = layout.IndexOf(ch);
//Проверка на длину символов
if (offset > pos)
{
pos = 32 - (offset - pos);
}
else
{
pos = pos - offset;
}
if (previous != null)
{
pos = (pos + previous.GetOffset()) % 32;
}
return (char)(1040 + 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 == 32)
{
offset = 0;
}
if (next != null && (offset + 1040) == ((notchPos - 1040) % 32)
+ 1040)
{
next.Move();
}
}
//Движение ротора назад
public void MoveBack()
{
//Проверка переполненности ротора
if (offset == 0)
{
offset = 32;
}
offset--;
}
//Получение данных
public void PutDataIn(char s)
{
cIn = s;
char c = s;
c = (char)(((c - 1040) + offset) % 32 + 1040);
//Проверки
if (next != null)
{
//Проблема должна скрываться в этом месте
c = layout.Substring((c - 1040), 1).ToCharArray()[0];
if ((((c - 1040) + (-offset)) % 32 + 1040) >= 1040)
{
c = (char)(((c - 1040) + (-offset)) % 32 + 1040);
}
else
{
c = (char)(((c - 1040) + (32 + (-offset))) % 32 + 1040);
}
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 - 1040), 1).ToCharArray()[0];
}
return c;
}
}
}
Код для запуска
using System;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
//Данные для шифрации
Rotor_Ru rr_1 = new Rotor_Ru("ВШЭМСРЬТЫЗКДЯЕЪЮНЦЩАЛУИГПЧЙФБХЖО", 'А');
Rotor_Ru rm_1 = new Rotor_Ru("ЯЧФЫЭВЪМЬУХЗНШСДАЖПЕБЦЩИЛЙТГЮКРО", 'Б');
Rotor_Ru rl_1 = new Rotor_Ru("ШЫЩПЖЮЙЧВГКХАЪФУЬЦЛТРЕНДМЯБЭСЗОИ", 'В');
Rotor_Ru reflector_1 = new
Rotor_Ru("ЮЙВЫБУХПИНЗЛРДКФСЩГЭЧОЯШТАЕЪМЬЦЖ", '\0');
rr_1.SetNextRotor(rm_1);
rm_1.SetNextRotor(rl_1);
rl_1.SetNextRotor(reflector_1);
rm_1.SetPreviousRotor(rr_1);
rl_1.SetPreviousRotor(rm_1);
reflector_1.SetPreviousRotor(rl_1);
Console.WriteLine("Enter message");
string message = Console.ReadLine();
Console.WriteLine("\nCrypt/Decrypt...");
//Считывание
char[] chIn = message.ToUpper().ToCharArray();
//Очистка данных
string final_message = "";
//Шифрация/Дешифрация
for (int i = 0; i < chIn.Length; i++)
{
if (chIn[i] >= 1040 && chIn[i] <= 1071)
{
rr_1.Move();
rr_1.PutDataIn(chIn[i]);
final_message += ("" + rr_1.GetDataOut());
}
}
Console.WriteLine("Result\n");
Console.WriteLine(final_message);
Console.ReadKey();
}
}
}
Класс английского ротора. Рабочий
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApp2
{
public class Rotor_Eng
{
//Описание переменных класса
private string layout;
private byte offset;
private Rotor_Eng previous, next;
private char cIn = '\0', notchPos;
//Конструктор класса ротора
public Rotor_Eng(string layout, char notchPos)
{
//Присвоение внутренним переменным класса значений
this.layout = layout;
this.previous = previous;
this.next = next;
this.notchPos = notchPos;
offset = 0;
}
//Получение раскладки
public string GetLayout()
{
return layout;
}
//Установить следующий ротор
public void SetNextRotor(Rotor_Eng next)
{
this.next = next;
}
//Установить предыдущий ротор
public void SetPreviousRotor(Rotor_Eng 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) + 65) //оо
{
next.Move();
}
}
//Движение ротора назад
public void MoveBack()
{
//Проверка переполненности ротора
if (offset == 0)
{
offset = 26;
}
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];
}
return c;
}
}
}
Код для запуска английского ротора
using System;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
//Данные для шифрации
Rotor_Eng rr = new Rotor_Eng("BDFHJLCPRTXVZNYEIWGAKMUSQO", 'A');
Rotor_Eng rm = new Rotor_Eng("AJDKSIRUXBLHWTMCQGZNPYFVOE", 'B');
Rotor_Eng rl = new Rotor_Eng("EKMFLGDQVZNTOWYHXUSPAIBRCJ", 'C');
Rotor_Eng reflector = new
Rotor_Eng("YRUHQSLDPXNGOKMIEBFZCWVJAT", '\0');
rr.SetNextRotor(rm);
rm.SetNextRotor(rl);
rl.SetNextRotor(reflector);
rm.SetPreviousRotor(rr);
rl.SetPreviousRotor(rm);
reflector.SetPreviousRotor(rl);
Console.WriteLine("Enter message");
string message = Console.ReadLine();
Console.WriteLine("\nCrypt/Decrypt...");
//Считывание
char[] chIn = message.ToUpper().ToCharArray();
//Очистка данных
string final_message = "";
//Шифрация/Дешифрация
for (int i = 0; i < chIn.Length; i++)
{
if (chIn[i] >= 65 && chIn[i] <= 90)
{
rr.Move();
rr.PutDataIn(chIn[i]);
final_message += ("" + rr.GetDataOut());
}
}
Console.WriteLine("Result\n");
Console.WriteLine(final_message);
Console.ReadKey();
}
}
}