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

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

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

Студворк — интернет-сервис помощи студентам
Есть код -шифрование с помощью регистра сдвига 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
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.09.2018, 13:21
Ответы с готовыми решениями:

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

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

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

48
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
18.09.2018, 14:10  [ТС]
Студворк — интернет-сервис помощи студентам
Элд Хасп, Да, работает. Я заменил три строки и работает как у вас. Теперь вопрос, как реализовать это - Программа должна запрашивать имя входного и выходного файлов, представления создаваемого многочлена и инициализующее значение. Разрядность РЗЛЗЗ(этого шифра с сдвигом) должна быть меньше или равна максимальной разрядности стандартных целочисленных типов данных (64 бит).
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
18.09.2018, 14:12
К стати по условиям задания, какой длины должен быть ключ? Я сделал здесь любой длины кратной 8, т.е. состоящий из любого количества байтов. Если ключ сделать кратным 32, 64, 128 и более битам, то желательно методы переделать - так обработка побайтно сильно снижает скорость.
0
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
18.09.2018, 14:12  [ТС]
Хм, сейчас гляну
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
18.09.2018, 14:18
Поняли же как вводить ключ? Введите 64 бита ключа.
Поток который надо зашифровать/расшифровать (это же зеркальный метод, насколько помню?) передаёте методу Encrypt. Он возвращает Вам зашифрованный/расшифрованный поток.

Добавлено через 2 минуты
Зашифрованный поток Вы не сможете вывести в символьном виде. Надо выводить побайтно в шестнадцатеричном коде.
Поэтому для сравнения, входной поток надо вначале показать в символьном виде, потом в шестнадцатеричном коде.
0
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
18.09.2018, 14:19  [ТС]
Элд Хасп, Мы же используем только 64 бита, ибо ключ становится регистром - ключ переводим в биты и это становится нашим начальным регистром . Он принимает не больше 64, можно сделать хоть динамическим его

Примеры для многочленов (16, 5, 3.2, 0) (32, 7, 6, 2, 0) (45, 4, 3, 1, 0) (63, 1, 0)
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
18.09.2018, 14:24
Цитата Сообщение от Алексей2332 Посмотреть сообщение
Хм, сейчас гляну
В принципе, для учебной задачи, если потоки не большие (мегабайты), то это не важно. Будет медленно, но для учёбы - сойдёт.

Добавлено через 2 минуты
Цитата Сообщение от Алексей2332 Посмотреть сообщение
Мы же используем только 64 бита
В моей реализации ключ может быть любое количество байтов. 64 бита - 8 байт. Токо Вы где-то запоминайте значение ключа - вводить каждый раз без ошибок 64 бита - та ещё морока.

Добавлено через 1 минуту
Цитата Сообщение от Алексей2332 Посмотреть сообщение
Примеры для многочленов...
Это что за многочлены?

Добавлено через 31 секунду
Для функции обратной связи регистра?
0
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
18.09.2018, 14:26  [ТС]
Элд Хасп, То, что я описывал выше. Само условие программы
Программа должна запрашивать имя входного и выходного файлов, представления создаваемого многочлена и инициализующее значение. Разрядность РЗЛЗЗ(этого шифра с сдвигом) должна быть меньше или равна максимальной разрядности стандартных целочисленных типов данных (64 бит).
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
18.09.2018, 14:30
Цитата Сообщение от Алексей2332 Посмотреть сообщение
представления создаваемого многочлена
Что это такое?

Добавлено через 1 минуту
Ещё раз. Это функция для обратной связи регистра?
0
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
18.09.2018, 14:44  [ТС]
Элд Хасп, Похоже на то . Вот по методичке
Для того чтобы конкретный РЗЛЗЗ имел максимальный период (то есть циклически проходил через все 2^(n) -1 внутренних состояний), многочлен, образованный из отводной последовательности, должен быть примитивным, то есть не разлагаться в произведение многочленов меньшей степени. Некоторые примитивные исполнительные многочлены приведены в табл. 1.1.
Перед запуском РЗЛЗЗ при шифровании или дешифровании, регистр необходимо инициализировать одним и тем же значением

Добавлено через 6 минут
Элд Хасп,
Вот для чего многочлены
Для того, чтобы определить какие манипуляции проводим с регистром, чтобы в регистре сделать новый бит. То есть если многочлен представлен в виде чисел по спадания через запятую (7,3,0) Первую игнорируем - оно означает длинну регистру. А следующие - какие елементы регистра ксорим, чтобы получить новый бит. Если 7,3,0, то ксорим 3 и 0 елемент регистра, сдвигаем регистр вправо
Правый крайний елемент - то что будет на выходе на этом такте из регистра - мой ключ, бит
А новый созданный бит после ксора 3 и 0 елемента регистра - засосываем в самый левую ячейку регистра
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
18.09.2018, 14:59
Цитата Сообщение от Алексей2332 Посмотреть сообщение
Похоже на то . Вот по методичке...
Да, именно то. У меня реализована функция (в Вашей записи) {N, N-1,1,0}, где N номер старшего бита. Эту функцию считает метод FeedbackBit. Если Вам нужен функционал по изменению этой функции, то замените FeedbackBit на делегат и передавайте функцию в параметрах.

Добавлено через 6 минут
Цитата Сообщение от Алексей2332 Посмотреть сообщение
засосываем в самый левую ячейку регистра
У меня сделано, немного по другому. Здесь же Вы имеете ввиду слева старшие биты? Реализация такая же, но представления в (двоичном, шестнадцатеричном виде) реализованы не справа налево, а слева направо. Т.е. слева младший разряд. так принято для потоков. Первый введённый символ - это младший символ.
Если надо по иному, то переделайте методы отвечающие за представления ToStringBinary() и ToStringHex().

Добавлено через 6 минут
Цитата Сообщение от Алексей2332 Посмотреть сообщение
...через запятую (7,3,0) Первую игнорируем - оно означает длинну регистру...
Вряд ли, т.к. старший бит почти всегда участвует в функции обратной связи. Поэтому его тоже надо задействовать.
Т.е это как в квадратном уравнении a*x^2 + b*x + с = 0, если a=0, то это уже не квадратное уравнение.
0
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
18.09.2018, 15:01  [ТС]
Элд Хасп, Хорошо. Как я понял разрядность мы задаем сами в зависимости от нашего ключа из 0 и 1
Для входного файла постараюсь переделать как вы сказали, а выходной файл - т.е инициализирующее значение?

Добавлено через 2 минуты
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Вряд ли, т.к. старший бит почти всегда участвует в функции обратной связи. Поэтому его тоже надо задействовать.
Т.е это как в квадратном уравнении a*x^2 + b*x + с = 0, если a=0, то это уже не квадратное уравнение.
Странно, мне объясняли именно так, что если мы представим в виде цифр, чисел по спаданию через запятую, то 1 мы игнорим
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
18.09.2018, 15:11
Цитата Сообщение от Алексей2332 Посмотреть сообщение
Странно, мне объясняли именно так...
Действительно - странно. Где-то недопонимание присутствует. Но для обеспечения максимального периода, старший бит почти всегда используется.
На своём примере, я проверял. Для 8 битов -даёт максимальный период - 255 шагов, для 16 - битов почти максимальный > 63 тысяч. Для большего количества битов - не запускал.
0
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
18.09.2018, 15:14  [ТС]
Элд Хасп, Ну да ладно, я завтра разберусь с этим до конца. Так , а что в вашем коде является выходным файлом, т.е инициализирующим значением. Его то по программе тоже надо вводить мне ручками
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
18.09.2018, 15:24
Цитата Сообщение от Алексей2332 Посмотреть сообщение
Так , а что в вашем коде является выходным файлом, т.е инициализирующим значением. Его то по программе тоже надо вводить мне ручками
Замучаетесь ручками.
Метод Encrypt ему надо передать поток, он вернёт поток. Я уже писал см. пост #24
0
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
18.09.2018, 21:06  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Замучаетесь ручками.
Метод Encrypt ему надо передать поток, он вернёт поток. Я уже писал см. пост #24
Понял. Хорошо, спасибо вам большое ^-^ . Переделаю Feedbackbit чуть позднее

Добавлено через 5 часов 16 минут
Элд Хасп, Оно то делает, что описывает. Но мне то нужно сделать консольный или оконный дополнение, что реализует описанный алгоритм потокового шифрования на базе этого шифра для шифрования cодержимого текстового или исполняемого файла.
То есть я задаю текст и оно шифрует с помощью этих самых сдвигов на основе многочлена
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
19.09.2018, 00:23
Посмотрите как делает. Возьмите оттуда что надо. Сделал ещё класс регистра на 64 бита.
Консольный метод
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
       static void Register() // Регистр
        {
 
 
            Console.WriteLine("  При вводе для разделения разрядов можно использовать пробел и подчёркивание.");
            Console.WriteLine("  Остальные символы не предусмотренные системой счисления приводят к ошибке.");
            Console.WriteLine("  Для шестнадцатеричной системы регистр значения не имеет.");
            Console.WriteLine("  Разряды вводятся от старших к младшим");
            Console.WriteLine("  Для шестнадцатеричной системы количество разрядов долно быть 16");
            Console.WriteLine("  Для десятичной системы количество разрядов долно быть 20");
            Console.WriteLine("  Для двоичной системы количество разрядов долно быть 64");
            Console.WriteLine();
 
            Cl_Register64 _reg;
            string TextInput;
            {
                FileStream _key_file = new FileStream("key.bin", FileMode.OpenOrCreate); // Попытка открытия файла ключа
 
                do
                {
                    Console.Write("  Введите шестнадцатеричный ключ (пустая строка - ключ буден прочитан из файла \"key.bin\":\n  ");
                    TextInput = Console.ReadLine();
                    if (string.IsNullOrWhiteSpace(TextInput))
                    {
                        Console.Write("  Ключ будет прочитан из файла");
                        if (_key_file.Length != 8) // Если в файле ключа 8 байт, то создание регистра
                        { Console.Write("  Нет файла ключа"); _reg = null; }
                        else
                        {
                            _reg = Cl_Register64.Create(new BinaryReader(_key_file).ReadUInt64());
                        }
                    }
                    else { _reg = Cl_Register64.CreateFromString(TextInput, Cl_Register64.TypeStringEnum.Hex); }
 
                } while (_reg == null);
 
                Console.WriteLine($"  Ключ в двоичном коде - {_reg.ToStringBinary()} ;\n  в шестнадцатеричном коде {_reg.ToStringHex()} .");
                Console.WriteLine();
                Console.WriteLine("  Ключ сохранён в \"key.bin\" ");
                _key_file.Seek(0, SeekOrigin.Begin); // Установка указателя на начало файла
                new BinaryWriter(_key_file).Write(_reg.InitialValue);
                _key_file.Close(); // Закрытие файла ключа 
            }
            Console.Write("  Введите текст для шифрования (пустая строка - текст буден прочитан из файла \"text.bin\":\n  ");
            do
            {
                TextInput = Console.ReadLine();
                if (string.IsNullOrEmpty(TextInput))
                {
                    Console.Write("  Попытка чтения текста из файла.");
                    try
                    {
                        Stream _text_file = new FileStream("text.bin", FileMode.OpenOrCreate); // Попытка открытия файла текста
                        TextInput = new BinaryReader(_text_file).ReadString();
                        _text_file.Close();
                    }
                    catch (Exception) { Console.Write("  В файле нет текста."); }
                }
                if (string.IsNullOrEmpty(TextInput))
                    Console.Write("  Нет текста для шифрования: строка: он пустой или состоит из пробелов.");
            } while (string.IsNullOrEmpty(TextInput));
            {
 
                Stream _text_file = new FileStream("text.bin", FileMode.Create); // Создание файла текста
                BinaryWriter _text_stream = new BinaryWriter(_text_file); // Создание двоичного потока записи
                _text_stream.Write(TextInput); // Запись в файл текста
 
                Console.WriteLine($"  Текст для шифрования \"{TextInput}\" ;\n  " +
                    $"в шестнадцатеричном коде {StreamToString(_text_file)} .");
                TextInput = null;
 
                MemoryStream _text_coding_stream = _reg.Encrypt(_text_file); // Получение зашифрованного текста
                _text_file.Close(); _text_file = null; // Закрытие потока и файла текста
                Stream _text_coding_file = new FileStream("text_coding.bin", FileMode.Create);
                _text_coding_stream.WriteTo(_text_coding_file);
 
                Console.WriteLine("\n  Зашифрованный текст запомнен в файле \"text_coding.bin\"\n  " +
                    $"  в шестнадцатеричном коде {StreamToString(_text_coding_stream)} .");
 
                _text_coding_file.Close(); _text_coding_file = null;
            }
            {
                Console.WriteLine("\n  Зашифрованный текст читается из файла \"text_coding.bin\"\n  ");
                Stream _text_coding_file = new FileStream("text_coding.bin", FileMode.Open);
                Console.WriteLine("\n  Расшифровка текста\"\n  ");
                MemoryStream _text_decoding_stream = _reg.Encrypt(_text_coding_file); // Получение расшифрованного текста
                _text_coding_file.Close();
                _text_decoding_stream.Seek(0, SeekOrigin.Begin);
                TextInput = new BinaryReader(_text_decoding_stream).ReadString(); // Чтение расшифрованного текста
            }
            {
                Console.WriteLine("\n  Запись расшифрованного текста в файл \"text_decoding.bin\"\n  ");
                Stream _text_file = new FileStream("text_decoding.bin", FileMode.Create); // Создание файла расшифрованного текста
                BinaryWriter _text_decoding_stream = new BinaryWriter(_text_file); // Создание двоичного потока записи
                _text_decoding_stream.Write(TextInput); // Запись в файл текста
 
 
                Console.WriteLine("\n  Расшифрованный текст запомнен в файле \"text_decoding.bin\"\n  " +
                    $"  Текст \"{TextInput}\"" +
                    $"\n    в шестнадцатеричном коде {StreamToString(_text_file)} .");
                _text_file.Close();
            }
 
 
            Console.Write("Для выхода нажмите любую клавишу.....   "); Console.ReadKey();
 
        }
 
        static string StreamToString(Stream stream)
        {
            stream.Seek(0, SeekOrigin.Begin);
            BinaryReader stream_bin = new BinaryReader(stream);
            string _ret = "";
            while (stream.Position<stream.Length )
            {
                _ret += Convert.ToString(stream_bin.ReadByte(), 16);
                if (stream.Position%2==0)
                {
                    if (stream.Position%4==0)
                    { _ret += " "; }
                    else
                    {_ret += "_"; }
                }
            }
            return _ret;
        }
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
19.09.2018, 00:44
Классы регистров: массив байтов и ulong (64 бита). И метод вывода потока в шестнадцатеричном коде.
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
        #region Реализация шифрования регистром с обратной связью Register() 
        static string StreamToString(Stream stream)
        {
            stream.Seek(0, SeekOrigin.Begin);
            BinaryReader stream_bin = new BinaryReader(stream);
            string _ret = "";
            while (stream.Position<stream.Length )
            {
                _ret += Convert.ToString(stream_bin.ReadByte(), 16);
                if (stream.Position%2==0)
                {
                    if (stream.Position%4==0)
                    { _ret += " "; }
                    else
                    {_ret += "_"; }
                }
            }
            return _ret;
        }
 
 
        /// <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;
            }
        }
 
        /// <summary>Класс 64-разрядного регистра с обратной связью</summary>
        class Cl_Register64
        {
            private ulong _initialValue; // Поле для начального состояния регистра
            private ulong _currentValue; // Поле для текущего состояния регистра
 
            /// <summary>Возвращает начальное значение регистра</summary>
            public ulong InitialValue { get => _initialValue; private set { _initialValue = value; CurrentValue = InitialValue; } }
 
            /// <summary>Возвращает суммарный сдвиг регистра</summary>
            public long TotalShift { get; private set; }
 
            /// <summary>Возвращает текущее значение регистра</summary>
            public ulong CurrentValue { get => _currentValue; private set { _currentValue = value; TotalShift = 0; } }
 
            /// <summary>Возвращает делегат функции обратной связи регистра</summary>
            public delegateFeedbackFunction FeedbackFunction { get; private set; }
 
            /// <summary>Сокрытие конструктора по умолчанию</summary>
            private Cl_Register64() { }
 
            /// Делегат для функкции обратной связи. Должна возвращать в старшем бите связь от состояния параметра.
            public delegate ulong delegateFeedbackFunction(ulong Register);
 
            /// <summary>Создание нового регистра</summary>
            /// <param name="NewValue">Начальное значение регистра</param>
            /// <param name="FeedbackFunction">Функция обратной связи</param>
            /// <returns>Новый объект Cl_Register</returns>
            static public Cl_Register64 Create(ulong NewValue, delegateFeedbackFunction FeedbackFunction = null)
                => new Cl_Register64() { InitialValue = NewValue, FeedbackFunction = FeedbackFunction == null ? FeedbackBit : FeedbackFunction };
 
            /// <summary>Перечислитель для типов строки</summary>
            public enum TypeStringEnum { Bynary = 0, Hex = 1, Decimal = 3 }
 
            /// <summary>Создание нового регистра из строковых данных для начального значения</summary>
            /// <param name="NewValue">Строка символов от младшего к старшему разряду</param>
            /// <param name="Type">Тип данных в строке</param>
            static public Cl_Register64 CreateFromString(string NewValue, TypeStringEnum Type, delegateFeedbackFunction FeedbackFunction = null)
            {
                if (FeedbackFunction == null) FeedbackFunction = FeedbackBit;
                NewValue = NewValue.Replace(" ", "").Replace("_", ""); // Удаляет из строки все пробелы и подчёркивания
                switch (Type)
                {
                    case TypeStringEnum.Bynary:
 
                        // Количество двоичных символов в исходной строке
                        int Count_char = NewValue.Count(_char => _char == '0' || _char == '1');
 
                        if (Count_char != NewValue.Length || Count_char != 64) // Определение некорректных данных
                        {
                            MessageBox.Show("Ошибка!\nПолученные данные для двоичного преобразования некорректны!");
                            return null;
                        }
 
                        // Конвертация из двоичной строки в ulong 
                        return Create(Convert.ToUInt64(NewValue, 2), FeedbackFunction);
                    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 != 16) // Определение некорректных данных
                        {
                            MessageBox.Show("Ошибка!\nПолученные данные для шестнадцатеричного преобразования некорректны!");
                            return null;
                        }
 
                        // Конвертация из шестнадцатеричной строки в ulong 
                        return Create(Convert.ToUInt64(NewValue, 16), FeedbackFunction);
 
                    case TypeStringEnum.Decimal:
                        Count_char = NewValue.Count(_char => _char >= '0' && _char <= '9');
 
                        if (Count_char != NewValue.Length || Count_char != 20 || !UInt64.TryParse(NewValue, out ulong _ret)) // Определение некорректных данных
                        {
                            MessageBox.Show("Ошибка!\nПолученные данные для шестнадцатеричного преобразования некорректны!");
                            return null;
                        }
 
                        // Конвертация из шестнадцатеричной строки в ulong 
                        return Create(_ret, FeedbackFunction);
                    default:
                        return null;
                }
            }
 
            /// <summary>Метод возвращающий строковое двоичное представление регистра</summary>
            public string ToStringBinary()
            {
                string _str = Convert.ToString((Int64)CurrentValue, 2).PadLeft(64, '0');
                string _ret = "";
 
                for (int IndChar = 0; IndChar < _str.Length; IndChar += 8) // Цикл по 8 символов
                { // "Красивый" формат двоичного вывода
                    _ret += " " + _str.Substring(IndChar, 4) + "_" + _str.Substring(IndChar + 4, 4);
                }
                return _ret;
            }
 
            /// <summary>Метод возвращающий строковое шестнадцатеричное представление регистра</summary>
            public string ToStringHex()
            {
                string _str = Convert.ToString((Int64)CurrentValue, 16).PadLeft(16, '0');
                string _ret = "";
 
                for (int IndChar = 0; IndChar < _str.Length; IndChar += 4) // Цикл по 8 символов
                { // "Красивый" формат двоичного вывода
                    _ret += " " + _str.Substring(IndChar, 2) + "_" + _str.Substring(IndChar + 2, 2);
                }
                return _ret;
            }
 
            /// <summary>Метод возвращающий младший бит регистра</summary>
            public ulong LowBit() => CurrentValue & 0b1;
            /// <summary>Метод возвращающий старший бит регистра</summary>
            public ulong MostBit() => CurrentValue & 0x8000_0000_0000_0000;
            /// <summary>Метод возвращающий младший байт регистра</summary>
            public byte LowByte() => (byte)(CurrentValue & 0x0000_0000_0000_00FF);
            /// <summary>Метод возвращающий старший байт регистра</summary>
            public byte MostByte() => (byte)(CurrentValue & 0xFF00_0000_0000_0000);
 
            /// <summary>Метод для функции обратной связи по умолчанию (X^63 + X^62 + X^1 + X^0)</summary>
            static public ulong FeedbackBit(ulong Register)
                  => ((Register & 0b1) << 63 ^ (Register & 0b10) << 62
                  ^ ((Register & 0x4000_0000_0000_0000) << 1) ^ (Register & 0x8000_0000_0000_0000)
                  );
 
            /// <summary>Метод сдвигающий регистр на один бит в сторону младших разрядов</summary>
            public void Step()
            {
                ulong _bit = FeedbackBit(CurrentValue);// Старший бит обратной связи
                CurrentValue >>= 1; // Сдвиг к младшим на 1 разряд
                CurrentValue |= _bit; // Запись в старший бита обратной связи
                TotalShift++; // Увелечение счётчика сдвигов
            }
 
            /// <summary>Метод сдвигающий регистр на один байт в сторону младших разрядов</summary>
            public void StepByte() { for (int Ind = 0; Ind < 8; Ind++) Step(); }
 
            /// <summary>Метод сдвигающий регистр на один 16 бит в сторону младших разрядов</summary>
            public void StepUInt16() { StepByte(); StepByte(); }
 
            /// <summary>Метод сдвигающий регистр на один 32 бита в сторону младших разрядов</summary>
            public void StepUInt32() { StepUInt16(); StepUInt16(); }
 
            /// <summary>Метод сдвигающий регистр на один 64 бита в сторону младших разрядов</summary>
            public void StepUInt64() { StepUInt32(); StepUInt32(); }
 
            /// <summary>Метод возвращающий зашифрованный поток</summary>
            public MemoryStream Encrypt(Stream stream)
            {
                stream.Seek(0, SeekOrigin.Begin); // Смещение указателя в начало потока
                Init(); // Установка регистра в начальное состояние
                MemoryStream stream_ret = new MemoryStream(); // Создание выходного потока в память
                BinaryWriter stream_ret_bin = new BinaryWriter(stream_ret); // Создание двоичного вывода в поток
                BinaryReader stream_out_bin = new BinaryReader(stream); // Создание двоичного ввода из потока
 
                while (stream.Position + 8 < stream.Length) // Определение есть или нет 8 байт до конца потока
                {
                    StepUInt64(); // Изменение состояния регистра на 64 бита
                    stream_ret_bin.Write(stream_out_bin.ReadUInt64() ^ CurrentValue);  // Считывание, шифрование и запись по 8 байт (64 бита)
                }
 
                while (stream.Position < stream.Length) // Определение есть или байт до конца потока
                {
                    StepByte(); // Изменение состояния регистра на 8 битов
                    stream_ret_bin.Write((byte)(stream_out_bin.ReadByte() ^ LowByte()));  // Считывание, шифрование и запись по 1 байту (8 битов)
                }
 
                return stream_ret;
            }
 
            /// <summary>Метод сбрасывающий сдвиги</summary>
            public void Init() { CurrentValue = InitialValue; }
 
 
 
            /// <summary>Метод возвращающий True, если текущее значение регистра равно начальному</summary>
            public bool ReturnedToBeginning() => _currentValue == _initialValue;
        }
 
        #endregion
Добавлено через 17 минут
Кстати, дополнил ещё возможностью задания функции обратной связи.
Передаются как делегат при создании регистра третьим параметром.
Функция получает как параметр текущее значение регистра типа ulong, возвращает значение обратной связи в типе ulong.
Можно формировать не только старший бит, а значения обратной связи для всех битов. Такие функции тоже есть.
0
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
19.09.2018, 12:37  [ТС]
Элд Хасп, Вот так
Миниатюры
Регистр сдвига c линейной обратной связью  
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
19.09.2018, 13:04
Похоже Вы где-то при копировании какие-то куски перемешали. Сейчас скину проект целиком - сверьтесь.
0
1 / 1 / 0
Регистрация: 06.09.2018
Сообщений: 40
19.09.2018, 13:11  [ТС]
Элд Хасп, немного лучше, но все же где ошибка
Миниатюры
Регистр сдвига c линейной обратной связью  
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.09.2018, 13:11

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru