Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.91/55: Рейтинг темы: голосов - 55, средняя оценка - 4.91
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
1

Регистр сдвига c линейной обратной связью

12.09.2018, 13:21. Показов 10365. Ответов 48
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть код -шифрование с помощью регистра сдвига c линейной обратной связью , который считывает правильно ,правильно выводит в консоль и расшифровывает правильно.
Но вместо вывода в шифрованом виде выводит ????
В чем проблема?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
 
namespace l2t1
{
    class Program
    {
        static void Main(string[] args)
        {
            String text;
            using (StreamReader sr = new StreamReader("D:\\текст.txt", System.Text.Encoding.UTF8, false))
            {
                text = sr.ReadLine();
            }
            lfsr t1 = new lfsr(text, 0, "10001110101011101110000111");
            Console.WriteLine("Текст: {0}", t1.CleanText);
            Console.WriteLine("Ключ: {0}", t1.Key);
            Console.WriteLine("Последовательность текста: {0}", t1.TextKey);
            Console.WriteLine("Псевдослучайная последовательность: {0}", t1.RandomKey);
            Console.WriteLine("Зашифрованный текст: {0}", t1.EncryptedText);
            Console.WriteLine("Расшифрованный текст: {0}", t1.DecryptedText);
            Console.Read();
            using (StreamWriter sw = new StreamWriter("D:\\output.txt"))
            {
                sw.WriteLine(t1.EncryptedText);
                sw.WriteLine(t1.DecryptedText);
            }
 
        }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
lfsr.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace l2t1
{
    class lfsr
    {
        private String encryptedText;
        private String cleanText;
        private String decryptedText;
        private String key;
        private String randomKey;
        private String textKey;
 
        public String EncryptedText
        {
            get { return encryptedText; }
            set { encryptedText = value; }
        }
        public String CleanText
        {
            get { return cleanText; }
            set { cleanText = value; }
        }
        public String DecryptedText
        {
            get { return decryptedText; }
            set { decryptedText = value; }
        }
        public String Key
        {
            get { return key; }
            set { key = value; }
        }
        public String RandomKey
        {
            get { return randomKey; }
            set { randomKey = value; }
        }
        public String TextKey
        {
            get { return textKey; }
            set { textKey = value; }
        }
 
        private String getCharTextKey(int ch)
        {
            String charkey = "";
            int a = 0, len = 15;
            while (len >= 0)
            {
                a = ch % 2;
                ch = ch / 2;
                if (a == 0) charkey = charkey.Insert(0, "0");
                else charkey = charkey.Insert(0, "1");
                len--;
            }
 
 
            return charkey;
        }
        private void MakeTextKey(String OurText)
        {
            String buff = "";
            for (int i = 0; i < OurText.Length; i++)
            {
                buff = getCharTextKey((int)OurText[i]);
                textKey = textKey.Insert(i * 16, buff);
                buff = "";
            }
        }
        private int xor(int x, int y)
        {
            if (((x == 0) && (y == 0)) || ((x == 1) && (y == 1))) return 0;
            else return 1;
        }
        private int MakeIt(int[] arr)
        {
            int forret = arr[25];
            int result = xor(arr[25], arr[15]);
            result = xor(result, arr[6]);
            result = xor(result, arr[0]);
 
            for (int i = 1; i < 26; i++) arr[i - 1] = arr[i];
 
            arr[25] = result;
            return forret;
        }
        private void CreateKey()
        {
            int[] reg = new int[26];
            for (int i = 0; i < 26; i++) reg[i] = (int)(key[i] - 48);
            for (int i = 0; i < (16 * cleanText.Length); i++)
            {
                if (MakeIt(reg) == 0) randomKey = randomKey.Insert(i, "0");
                else randomKey = randomKey.Insert(i, "1");
            }
 
        }
        private char BinToInt(int[] arr, int k)
        {
            int sum = 0, raz = 1;
            for (int i = 15; i != -1; i--)
            {
                sum += arr[i + k * 16] * raz;
                raz *= 2;
            }
            return (char)sum;
        }
        private void Encrypt()
        {
            encryptedText = "";
            int[] finalkey = new int[randomKey.Length];
            for (int i = 0; i < randomKey.Length; i++)
                finalkey[i] = xor(randomKey[i] - 48, textKey[i] - 48);
 
            for (int i = 0; i < cleanText.Length; i++)
            {
                encryptedText = encryptedText.Insert(i, BinToInt(finalkey, i).ToString());
            }
 
        }
        private void Decrypt()
        {
            decryptedText = "";
            MakeTextKey(encryptedText);
            int[] finalkey = new int[randomKey.Length];
            for (int i = 0; i < randomKey.Length; i++)
                finalkey[i] = xor(randomKey[i] - 48, textKey[i] - 48);
 
            char ch;
            for (int i = 0; i < encryptedText.Length; i++)
            {
                ch = BinToInt(finalkey, i);
                decryptedText = decryptedText.Insert(i, ch.ToString());
            }
        }
 
        public lfsr(String _text, int k, String _key)
        {
            textKey = "";
            randomKey = "";
            cleanText = "";
            encryptedText = "";
            if (k == 0) decryptedText = _text;
            else encryptedText = _text;
            cleanText = _text;
 
            key = _key;
            MakeTextKey(cleanText);
            CreateKey();
            Encrypt();
            Decrypt();
        }
 
    }
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.09.2018, 13:21
Ответы с готовыми решениями:

Регистр сдвига с линейной обратной связью
И так пишу значит регистр сдвига. Уже значения генерируются успешно. Вот только генерация идет без...

Шифровальщик по принципу регистра сдвига c линейной обратной связью не работает с русским текстом
Всем доброе время суток! Возникла следующая проблема: я написал шифровальщик по принципу регистра...

Служба Windows с фоновой работой и обратной связью
Всем привет! Хочу реализовать службу Windows, которая с момента запуска и до момента остановки...

Регистр сдвига с линейной обратной связью
Собственно вопрос, как реализовать LFSR на Си???

48
Эксперт JS
6492 / 3903 / 2005
Регистрация: 14.06.2018
Сообщений: 6,781
12.09.2018, 13:32 2
Алексей2332, консоль по умолчанию выводит в кодировке cp-866. Поэтому и знаки вопроса.
0
Модератор
Эксперт .NET
15466 / 10712 / 2786
Регистрация: 21.04.2018
Сообщений: 31,532
Записей в блоге: 2
12.09.2018, 13:34 3
Цитата Сообщение от Алексей2332 Посмотреть сообщение
В чем проблема?
У Вас 200 строк кода и не одного комментария. Как разбираться? Только для понимания что-куда надо потратить не мало времени.
Закомментируйте хотя бы методы и свойства и комментируйте не "//...." , а "///<summary>......".
0
Эксперт JS
6492 / 3903 / 2005
Регистрация: 14.06.2018
Сообщений: 6,781
12.09.2018, 13:54 4
C#
1
Console.WriteLine("Зашифрованный текст: {0}", t1.EncryptedText);
Здесь явно непечатный текст. Консоль не знает, что выводить.
Даже не спасает
C#
1
Console.OutputEncoding = Encoding.UTF8;
0
Модератор
Эксперт .NET
15466 / 10712 / 2786
Регистрация: 21.04.2018
Сообщений: 31,532
Записей в блоге: 2
12.09.2018, 14:29 5
amr-now, там в самом классе lfsr с данными работают, то как с числами, то как с символами. Без пол литра не разберёшься.
По самому смыслу шифрования, надо входные данные конвертировать в числовые (при этом отбросить всё лишнее и сжать) и хранить, обрабатывать в таком виде, а при запросе на вывод проводить обратную конвертацию. Но сделано совсем по другому. Например, по смыслу двоичный ключ хранится как строка символов.
Отсюда и вся путаница.
0
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
12.09.2018, 15:29  [ТС] 6
amr-now, И как исправить ?
0
Эксперт JS
6492 / 3903 / 2005
Регистрация: 14.06.2018
Сообщений: 6,781
12.09.2018, 16:00 7
Алексей2332, а не надо никак выводить. Зашифрованный текст не требует вывода на консоль по своему смыслу.
Вывести надпись: TOP SECRET и всё.
0
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
12.09.2018, 16:04  [ТС] 8
amr-now, Боюсь меня не поймут, это же для универа
0
Эксперт JS
6492 / 3903 / 2005
Регистрация: 14.06.2018
Сообщений: 6,781
12.09.2018, 16:09 9
Алексей2332, Вам никто не мешает вывести шифровку типа круто числами байтами. Юстас Алексу.

Преподы в осадок выпадут!
0
Модератор
Эксперт .NET
15466 / 10712 / 2786
Регистрация: 21.04.2018
Сообщений: 31,532
Записей в блоге: 2
12.09.2018, 18:02 10
Цитата Сообщение от Алексей2332 Посмотреть сообщение
amr-now, И как исправить ?
Выводите в шестнадцатиричном виде.

Добавлено через 10 минут
По самому алгоритму. Как я понял, ключ шифрования это свойство Key. устанавливается оно у Вас только в одном месте - в конструкторе класса. Больше нигде его значение не используется.
Или я не внимательно смотрел код.... Или Вы неправильно реализовали шифрование и получили, вместо шифрования, просто перестановку битов.

Добавлено через 6 минут
Насколько помню, этот алгоритм требует сначала сжатия информации (GZipStream - возможно?) И потом наложение ключа (исключающее или) на сжатый код с последовательным параллельным сдвигом кода и ключа.
Даже, если опустить часть со сжатием/распаковкой, то всё равно - наложения ключа у Вас нет.
0
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
13.09.2018, 08:56  [ТС] 11
Элд Хасп, понял,, надо будет заняться. Вы не сможете мне помочь?
0
Модератор
Эксперт .NET
15466 / 10712 / 2786
Регистрация: 21.04.2018
Сообщений: 31,532
Записей в блоге: 2
13.09.2018, 10:37 12
Я эти алгоритмы очень смутно помню. Учил всё это лет 30 назад.
У Вас же не реальная, а учебная задача? Если да, то можно пренебречь сжатием/рассжатием - это влияет только на возможность вскрытия шифра.
Сам детальный алгоритм шифрования скиньте сюда - постараюсь помочь.
Но Вам по любому понадобится проштудироватиь способы работы с двоичными (битовыми) данными - это основа почти всех методов шифрования.
0
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
13.09.2018, 10:43  [ТС] 13
Элд Хасп, да, мне нужно потоковое шифрование при помощи регистра сдвига с линейной обратной связью. Спасибо, мне бы очень не помешала помощь, а насчет теории я посмотрю, спасибо. Методичку попозже покажу, но явного условия там нет
0
Модератор
Эксперт .NET
15466 / 10712 / 2786
Регистрация: 21.04.2018
Сообщений: 31,532
Записей в блоге: 2
13.09.2018, 20:15 14
Сделал класс регистра. И программу для проверки. Посмотрите как должен он работать.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
        static void Main(string[] args)
        {
            Console.WriteLine("При вводе для разделения разрядов можно использовать пробел.");
            Console.WriteLine("Для шестнадцатеричной системы регистр значения не имеет.");
            Console.WriteLine("Остальные символы не предусмотренные системой счисления приводят к ошибке.");
            Console.WriteLine("Разряды вводятся от младших к старшим");
            Console.WriteLine("Для шестнадцатеричной системы количество разрядов долно быть чётным");
            Console.WriteLine("Для двоичной системы количество разрядов долно быть кратно 8");
            Console.WriteLine();
 
            Cl_Register _reg;
            string ExampleKey;
 
            do
            {
                Console.Write("Введите двоичный ключ: ");
                ExampleKey = Console.ReadLine();
 
                _reg = Cl_Register.CreateFromString(ExampleKey, Cl_Register.TypeStringEnum.Bynary);
            } while (_reg == null);
            Console.WriteLine($"Вы ввели в двоичном коде - {_reg.ToStringBinary()} ; в шестнадцатеричном коде {_reg.ToStringHex()} .");
            Console.WriteLine();
            do
            {
                Console.Write("Введите шестнадцатеричный ключ: ");
                ExampleKey = Console.ReadLine();
 
                _reg = Cl_Register.CreateFromString(ExampleKey, Cl_Register.TypeStringEnum.Hex);
            } while (_reg == null);
            Console.WriteLine($"Вы ввели в двоичном коде - {_reg.ToStringBinary()} ; в шестнадцатеричном коде {_reg.ToStringHex()} .");
            Console.WriteLine();
 
            Console.WriteLine("Высисление периода регистра");
            do
            {
                Console.WriteLine($"Шаг {_reg.TotalShift}.Значени регистра  (Bin){_reg.ToStringBinary()} ; (Hex){_reg.ToStringHex()} .");
                _reg.Step();
            } while (!_reg.ReturnedToBeginning());
            Console.Write("Для выхода нажмите любую клавишу.....   "); Console.ReadKey();
 
        }
    }
 
    /// <summary>Класс для хранения данных регистра</summary>
    class Cl_Register
    {
        private byte[] _initialValue;
        private byte[] _currentValue;
 
        /// <summary>Возвращает начальное значение регистра</summary>
        public byte[] InitialValue { get => _initialValue; private set { _initialValue = value; CurrentValue = InitialValue; } }
 
        /// <summary>Возвращает суммарный сдвиг регистра</summary>
        public long TotalShift { get; private set; }
 
        /// <summary>Возвращает текущее значение регистра</summary>
        public byte[] CurrentValue { get => _currentValue; private set { _currentValue = (byte[])value.Clone(); TotalShift = 0; } }
 
        /// <summary>Сокрытие конструктора по умолчанию</summary>
        private Cl_Register() { }
 
        /// <summary>Создание нового регистра</summary>
        /// <param name="NewValue">Массив байтов для начального значения регистра</param>
        /// <returns>Новый объект Cl_Register</returns>
        static public Cl_Register Create(byte[] NewValue) => new Cl_Register() { InitialValue = NewValue };
 
        /// <summary>Перечислитель для типов строки</summary>
        public enum TypeStringEnum { Bynary = 0, Hex = 1, Decimal = 3 }
 
        /// <summary>Создание нового регистра из строковых данных для начального значения</summary>
        /// <param name="NewValue">Строка символов от младшего к старшему разряду</param>
        /// <param name="Type">Тип данных в строке</param>
        static public Cl_Register CreateFromString(string NewValue, TypeStringEnum Type)
        {
            NewValue = NewValue.Replace(" ", ""); // Удаляет из строки все пробелы
            switch (Type)
            {
                case TypeStringEnum.Bynary:
 
                    // Количество двоичных символов в исходной строке
                    int Count_char = NewValue.Count(_char => _char == '0' || _char == '1');
 
                    if (Count_char != NewValue.Length || Count_char % 8 != 0) // Определение некорректных данных
                    {
                        MessageBox.Show("Ошибка!\nПолученные данные для двоичного преобразования некорректны!");
                        return null;
                    }
 
                    // Подготовка массива для данных
                    byte[] retValue = new byte[NewValue.Length / 8];
                    for (int IndByte = 0; IndByte < retValue.Length; IndByte++) // Цикл по байтам
                    {
                        retValue[IndByte] = Convert.ToByte(new string(NewValue.Substring(IndByte * 8, 8).Reverse().ToArray()), 2);
                    }
                    return Create(retValue);
                case TypeStringEnum.Hex:
                    NewValue = NewValue.ToUpper(); // Перевод строки в верхний регистр
                    // Ссылка на перебор шестнацатиричных символов в исходной строке
                    Count_char = NewValue.Count(_char => _char >= '0' && _char <= '9' || _char >= 'A' && _char <= 'F');
 
                    if (Count_char != NewValue.Length || Count_char % 2 != 0) // Определение некорректных данных
                    {
                        MessageBox.Show("Ошибка!\nПолученные данные для шестнадцатиричного преобразования некорректны!");
                        return null;
                    }
 
                    // Подготовка массива для данных
                    retValue = new byte[NewValue.Length / 2];
                    for (int IndByte = 0; IndByte < retValue.Length; IndByte++) // Цикл по байтам
                    {
                        int begChar = IndByte * 2; // Номер первого символа для байта
                        retValue[IndByte] = Convert.ToByte(new string(NewValue.Substring(IndByte * 2, 2).Reverse().ToArray()), 16);
                    }
                    return Create(retValue);
 
                case TypeStringEnum.Decimal:
                    // Реализция требует преобразования сначала в десятичное число, потом в двоичное, потом в массив байтов
                    // Требует работы с числами большого размера > 128
                    // Из-за сложности для учебного примера нет смысла в реализации
                    return null;
                default:
                    return null;
            }
        }
 
        /// <summary>Метод возвращающий строковое двоичное представление регистра</summary>
        public string ToStringBinary()
        {
            string _str = "";
            for (int IndByte = CurrentValue.Length - 1; IndByte >= 0; IndByte--) // Цикл по байтам в обратном порядке - от старших к младшим
            {
                // Преобразуемый байт CurrentValue[IndByte];
                _str += new string(Convert.ToString(CurrentValue[IndByte], 2).PadLeft(8, '0').Reverse().ToArray()) + " ";
            }
            return _str;
        }
 
        /// <summary>Метод возвращающий строковое шестнадцатиричное представление регистра</summary>
        public string ToStringHex()
        {
            string _str = "";
            for (int IndByte = CurrentValue.Length - 1; IndByte >= 0; IndByte--) // Цикл по байтам в обратном порядке - от старших к младшим
            {
                // Преобразуемый байт CurrentValue[IndByte];
                _str += new string(CurrentValue[IndByte].ToString("X").PadLeft(2, '0').Reverse().ToArray()) + " ";
            }
            return _str;
        }
 
        /// <summary>Метод возвращающий младший бит регистра</summary>
        public byte LowBit() => (byte)(CurrentValue[0] & 0b1);
 
        /// <summary>Метод возвращающий бит обратной связи (X^n + Xn-1 +X^1+1)</summary>
        public byte FeedbackBit() => (byte)((CurrentValue[0] & 0b1) ^ (CurrentValue[0] & 0b10)>>1 ^ ((CurrentValue[CurrentValue.Length - 1] & 0b0100_0000) >> 6) ^ ((CurrentValue[CurrentValue.Length - 1] & 0b1000_0000) >> 7));
 
        /// <summary>Метод сдвигающий регистр на один бит в сторону младших разрядов</summary>
        public void Step()
        {
            // Страший бит для заполнения байта. Инициализирован битом обратной связи
            byte _bit = FeedbackBit();
 
            for (int IndByte = CurrentValue.Length - 1; IndByte >= 0; IndByte--) // Цикл по байтам в обратном порядке - от старших к младшим
            {
                byte buf_byte = CurrentValue[IndByte]; // Запоминание текущего байта
                CurrentValue[IndByte] >>= 1; // Сдвиг текущего байта к младшим битам. В старшем бите 0.
                _bit <<= 7; // Сдвиг сохранённого бита из младшего в старший. Остальные биты = 0
                CurrentValue[IndByte] |= _bit; // Запись старшего бита в байт
                _bit = buf_byte; // Сохранение бита сдвига для следующего байта
            }
            TotalShift++; // Увелечение счётчика сдвигов
        }
 
        /// <summary>Метод сбрасывающий сдвиги</summary>
        public void Init() { CurrentValue = InitialValue; }
 
        /// <summary>Метод возвращающий True, если текущее значение регистра равно начальному</summary>
        public bool ReturnedToBeginning()
        {
            for (int IndByte = 0; IndByte < _currentValue.Length; IndByte++)
            {
                if (_currentValue[IndByte] != _initialValue[IndByte])
                    return false;
            }
            return true;
        }
 
    }
0
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
18.09.2018, 13:08  [ТС] 15
Элд Хасп, Ругается вот так
Миниатюры
Регистр сдвига c линейной обратной связью  
0
Модератор
Эксперт .NET
15466 / 10712 / 2786
Регистрация: 21.04.2018
Сообщений: 31,532
Записей в блоге: 2
18.09.2018, 13:38 16
Первая ошибка. В проекте нет точки входа - нет static void Main(string[] args). Вы или стёрли её или создали проект не как консольное приложение.
Вторая ошибка. Нет имени MessageBox. Наведите на место в коде где используется MessageBox - оно будет подчёркнуто красным. И всплывёт меню "Быстрое решение". В нём выберите вставить пространство System.Windows
Миниатюры
Регистр сдвига c линейной обратной связью   Регистр сдвига c линейной обратной связью   Регистр сдвига c линейной обратной связью  

0
Модератор
Эксперт .NET
15466 / 10712 / 2786
Регистрация: 21.04.2018
Сообщений: 31,532
Записей в блоге: 2
18.09.2018, 13:48 17
По первой ошибке, может быть и наоборот у Вас больше чем одна static void Main(string[] args)

Добавлено через 1 минуту
Как шифровать поток байтов с использованием класса регистра разобрались?

Добавлено через 5 минут
Вот класс дополненный методом шифрования потока
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
        #region Реализация шифрования регистром с обратной связью Register() 
        static void Register() // Регистр
        {
            Console.WriteLine("При вводе для разделения разрядов можно использовать пробел.");
            Console.WriteLine("Для шестнадцатеричной системы регистр значения не имеет.");
            Console.WriteLine("Остальные символы не предусмотренные системой счисления приводят к ошибке.");
            Console.WriteLine("Разряды вводятся от младших к старшим");
            Console.WriteLine("Для шестнадцатеричной системы количество разрядов долно быть чётным");
            Console.WriteLine("Для двоичной системы количество разрядов долно быть кратно 8");
            Console.WriteLine();
 
            Cl_Register _reg;
            string ExampleKey;
 
            do
            {
                Console.Write("Введите двоичный ключ: ");
                ExampleKey = Console.ReadLine();
 
                _reg = Cl_Register.CreateFromString(ExampleKey, Cl_Register.TypeStringEnum.Bynary);
            } while (_reg == null);
            Console.WriteLine($"Вы ввели в двоичном коде - {_reg.ToStringBinary()} ; в шестнадцатеричном коде {_reg.ToStringHex()} .");
            Console.WriteLine();
            do
            {
                Console.Write("Введите шестнадцатеричный ключ: ");
                ExampleKey = Console.ReadLine();
 
                _reg = Cl_Register.CreateFromString(ExampleKey, Cl_Register.TypeStringEnum.Hex);
            } while (_reg == null);
            Console.WriteLine($"Вы ввели в двоичном коде - {_reg.ToStringBinary()} ; в шестнадцатеричном коде {_reg.ToStringHex()} .");
            Console.WriteLine();
 
            Console.WriteLine("Высисление периода регистра");
            do
            {
                Console.WriteLine($"Шаг {_reg.TotalShift}.Значени регистра  (Bin){_reg.ToStringBinary()} ; (Hex){_reg.ToStringHex()} .");
                _reg.Step();
            } while (!_reg.ReturnedToBeginning());
            Console.Write("Для выхода нажмите любую клавишу.....   "); Console.ReadKey();
 
        }
    }
 
    /// <summary>Класс для хранения данных регистра</summary>
    class Cl_Register
    {
        private byte[] _initialValue;
        private byte[] _currentValue;
 
        /// <summary>Возвращает начальное значение регистра</summary>
        public byte[] InitialValue { get => _initialValue; private set { _initialValue = value; CurrentValue = InitialValue; } }
 
        /// <summary>Возвращает суммарный сдвиг регистра</summary>
        public long TotalShift { get; private set; }
 
        /// <summary>Возвращает текущее значение регистра</summary>
        public byte[] CurrentValue { get => _currentValue; private set { _currentValue = (byte[])value.Clone(); TotalShift = 0; } }
 
        /// <summary>Сокрытие конструктора по умолчанию</summary>
        private Cl_Register() { }
 
        /// <summary>Создание нового регистра</summary>
        /// <param name="NewValue">Массив байтов для начального значения регистра</param>
        /// <returns>Новый объект Cl_Register</returns>
        static public Cl_Register Create(byte[] NewValue) => new Cl_Register() { InitialValue = NewValue };
 
        /// <summary>Перечислитель для типов строки</summary>
        public enum TypeStringEnum { Bynary = 0, Hex = 1, Decimal = 3 }
 
        /// <summary>Создание нового регистра из строковых данных для начального значения</summary>
        /// <param name="NewValue">Строка символов от младшего к старшему разряду</param>
        /// <param name="Type">Тип данных в строке</param>
        static public Cl_Register CreateFromString(string NewValue, TypeStringEnum Type)
        {
            NewValue = NewValue.Replace(" ", ""); // Удаляет из строки все пробелы
            switch (Type)
            {
                case TypeStringEnum.Bynary:
 
                    // Количество двоичных символов в исходной строке
                    int Count_char = NewValue.Count(_char => _char == '0' || _char == '1');
 
                    if (Count_char != NewValue.Length || Count_char % 8 != 0) // Определение некорректных данных
                    {
                        MessageBox.Show("Ошибка!\nПолученные данные для двоичного преобразования некорректны!");
                        return null;
                    }
 
                    // Подготовка массива для данных
                    byte[] retValue = new byte[NewValue.Length / 8];
                    for (int IndByte = 0; IndByte < retValue.Length; IndByte++) // Цикл по байтам
                    {
                        retValue[IndByte] = Convert.ToByte(new string(NewValue.Substring(IndByte * 8, 8).Reverse().ToArray()), 2);
                    }
                    return Create(retValue);
                case TypeStringEnum.Hex:
                    NewValue = NewValue.ToUpper(); // Перевод строки в верхний регистр
                                                   // Ссылка на перебор шестнацатиричных символов в исходной строке
                    Count_char = NewValue.Count(_char => _char >= '0' && _char <= '9' || _char >= 'A' && _char <= 'F');
 
                    if (Count_char != NewValue.Length || Count_char % 2 != 0) // Определение некорректных данных
                    {
                        MessageBox.Show("Ошибка!\nПолученные данные для шестнадцатиричного преобразования некорректны!");
                        return null;
                    }
 
                    // Подготовка массива для данных
                    retValue = new byte[NewValue.Length / 2];
                    for (int IndByte = 0; IndByte < retValue.Length; IndByte++) // Цикл по байтам
                    {
                        int begChar = IndByte * 2; // Номер первого символа для байта
                        retValue[IndByte] = Convert.ToByte(new string(NewValue.Substring(IndByte * 2, 2).Reverse().ToArray()), 16);
                    }
                    return Create(retValue);
 
                case TypeStringEnum.Decimal:
                    // Реализация требует преобразования сначала в десятичное число, потом в двоичное, потом в массив байтов
                    // Требует работы с числами большого размера > 128
                    // Из-за сложности для учебного примера нет смысла в реализации
                    return null;
                default:
                    return null;
            }
        }
 
        /// <summary>Метод возвращающий строковое двоичное представление регистра</summary>
        public string ToStringBinary()
        {
            string _str = "";
            for (int IndByte = CurrentValue.Length - 1; IndByte >= 0; IndByte--) // Цикл по байтам в обратном порядке - от старших к младшим
            {
                // Преобразуемый байт CurrentValue[IndByte];
                _str += new string(Convert.ToString(CurrentValue[IndByte], 2).PadLeft(8, '0').Reverse().ToArray()) + " ";
            }
            return _str;
        }
 
        /// <summary>Метод возвращающий строковое шестнадцатеричное представление регистра</summary>
        public string ToStringHex()
        {
            string _str = "";
            for (int IndByte = CurrentValue.Length - 1; IndByte >= 0; IndByte--) // Цикл по байтам в обратном порядке - от старших к младшим
            {
                // Преобразуемый байт CurrentValue[IndByte];
                _str += new string(CurrentValue[IndByte].ToString("X").PadLeft(2, '0').Reverse().ToArray()) + " ";
            }
            return _str;
        }
 
        /// <summary>Метод возвращающий младший бит регистра</summary>
        public byte LowBit() => (byte)(CurrentValue[0] & 0b1);
        /// <summary>Метод возвращающий старший бит регистра</summary>
        public byte MostBit() => (byte)(CurrentValue[CurrentValue.Length - 1] & 0b1000_0000 >> 7);
        /// <summary>Метод возвращающий младший байт регистра</summary>
        public byte LowByte() => CurrentValue[0];
        /// <summary>Метод возвращающий старший байт регистра</summary>
        public byte MostByte() => CurrentValue[CurrentValue.Length - 1];
 
        /// <summary>Метод возвращающий бит обратной связи (X^n + X^n-1 + X^1 + 1)</summary>
        public byte FeedbackBit()
            => (byte)((CurrentValue[0] & 0b1) ^ (CurrentValue[0] & 0b10) >> 1
            ^ ((CurrentValue[CurrentValue.Length - 1] & 0b0100_0000) >> 6) ^ ((CurrentValue[CurrentValue.Length - 1] & 0b1000_0000) >> 7)
            );
 
        /// <summary>Метод сдвигающий регистр на один бит в сторону младших разрядов</summary>
        public void Step()
        {
            // Старший бит для заполнения байта. Инициализирован битом обратной связи
            byte _bit = FeedbackBit();
 
            for (int IndByte = CurrentValue.Length - 1; IndByte >= 0; IndByte--) // Цикл по байтам в обратном порядке - от старших к младшим
            {
                byte buf_byte = CurrentValue[IndByte]; // Запоминание текущего байта
                CurrentValue[IndByte] >>= 1; // Сдвиг текущего байта к младшим битам. В старшем бите 0.
                _bit <<= 7; // Сдвиг сохранённого бита из младшего в старший. Остальные биты = 0
                CurrentValue[IndByte] |= _bit; // Запись старшего бита в байт
                _bit = buf_byte; // Сохранение бита сдвига для следующего байта
            }
            TotalShift++; // Увелечение счётчика сдвигов
        }
 
        /// <summary>Метод сдвигающий регистр на один байт в сторону младших разрядов</summary>
        public void StepByte() { for (int Ind = 0; Ind < 8; Ind++) Step(); }
 
        /// <summary>Метод возвращающий зашифрованный поток</summary>
        public MemoryStream Encrypt(MemoryStream stream)
        {
            MemoryStream stream_ret = new MemoryStream();
            stream.Seek(0, SeekOrigin.Begin);
            Init();
            for (long Ind = 0; Ind < stream.Length; Ind++)
            {
                StepByte();
                stream_ret.WriteByte((byte)(stream.ReadByte() ^ MostByte()));
            }
            return stream_ret;
        }
 
        /// <summary>Метод сбрасывающий сдвиги</summary>
        public void Init() { CurrentValue = InitialValue; }
 
 
 
        /// <summary>Метод возвращающий True, если текущее значение регистра равно начальному</summary>
        public bool ReturnedToBeginning()
        {
            for (int IndByte = 0; IndByte < _currentValue.Length; IndByte++)
            {
                if (_currentValue[IndByte] != _initialValue[IndByte])
                    return false;
            }
            return true;
        }
        #endregion
0
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
18.09.2018, 13:49  [ТС] 18
Элд Хасп, Подключил, но ошибка осталась та же. Я попробовал вместо поставить Console.WriteLine
Но выходит так

Сейчас гляну выше
Миниатюры
Регистр сдвига c линейной обратной связью  
0
Модератор
Эксперт .NET
15466 / 10712 / 2786
Регистрация: 21.04.2018
Сообщений: 31,532
Записей в блоге: 2
18.09.2018, 13:55 19
Двоичный ключ вводится единицами и нулями
0
Модератор
Эксперт .NET
15466 / 10712 / 2786
Регистрация: 21.04.2018
Сообщений: 31,532
Записей в блоге: 2
18.09.2018, 14:03 20
Вот скриншоты
Миниатюры
Регистр сдвига c линейной обратной связью   Регистр сдвига c линейной обратной связью  
0
18.09.2018, 14:03
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.09.2018, 14:03
Помогаю со студенческими работами здесь

Линейный рекуррентный регистр сдвига с обратной связью, реализация на python
Доброго всем времени суток. Помогите довести задание по информатике до ума! Определить для...

Линейный регистр с обратной связью
Помогите пожалуйста написать линейный регистр с обратной связью на С++.

Помогите с обратной связью связью
Существует Таблица 'Справочник цен' и Форма 'Заказы' на ней есть поле со списком куда подставлены...

Гаммирование с обратной связью
Нужна помощь ребят. Я не програмист и С++ учил только самые основы, но в универе по предмету...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru