Почему шифрация/дешифрация происходит неверно?

Код запускается и работает, однако шифрация и дешифрация происходят некорректно. Для запуска кода требуется добавить класс ротора. Код основного файла представлен ниже класса ротора. Проблема заключается в том, что сообщение возможно зашифровать, однако не получается дешифровать(получить исходное). (Уточнение, после шифрации требуется перезапустить программу и вставить шифртекст, после чего пробовать дешифровать.)

Класс ротора

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();
        }
    }
}

Ответы (0 шт):