Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/56: Рейтинг темы: голосов - 56, средняя оценка - 4.50
11 / 10 / 1
Регистрация: 05.02.2012
Сообщений: 106

Сеть Фейстеля, неправильно работает

15.03.2014, 19:40. Показов 10361. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Мне надо было в учебных целях реализовать сеть Фейстеля, как на картинке.
И в итоге у меня получилось так, что при расшифровке в каждом четном блоке из 4-х символов 2-е неверны.
В коде для всех блоков я использую одну и ту же функцию, поэтому никак не могу понять, как так получается вообще?? Помогите пожалуйста разобраться.
Вот код:
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
        //str - исходная строка
        public static string feistel_crypt(string str, string key)
        {
            byte[] str_arr = Encoding.Default.GetBytes(str);
            byte[] key_arr = Encoding.Default.GetBytes(key);
            byte[] res_arr = new byte[str_arr.Length];
 
            for (int i = 0; i < str_arr.Length; i = i + 8)
            {
                byte[] block = new byte[8];
 
                for (int j = 0; j < 9; j++)
                {
                    Array.Copy(str_arr, i, block, 0, 8);
                    byte[] subblock_left_arr = new byte[4];
                    Array.Copy(block, subblock_left_arr, 4);
                    byte[] subblock_right_arr = new byte[4];
                    Array.Copy(block, 4, subblock_right_arr, 0, 4);
 
                    byte[] subblock_key_arr = new byte[4];
                    Array.Copy(key_arr, subblock_key_arr, 4);
                    subblock_key_arr = shift_key_left(key_arr, j);
 
                    block = crypt_block(subblock_left_arr, subblock_right_arr, subblock_key_arr, false);
                }
 
                //последний проход должен быть без перемены местами правого и левого подблока
                Array.Copy(str_arr, i, block, 0, 8);
                byte[] subblock_left_arr_l = new byte[4];
                Array.Copy(block, subblock_left_arr_l, 4);
                byte[] subblock_right_arr_l = new byte[4];
                Array.Copy(block, 4, subblock_right_arr_l, 0, 4);
 
                byte[] subblock_key_arr_l = new byte[4];
                Array.Copy(key_arr, subblock_key_arr_l, 4);
                subblock_key_arr_l = shift_key_left(key_arr, 9);
 
                block = crypt_block(subblock_left_arr_l, subblock_right_arr_l, subblock_key_arr_l, true);
 
 
                Array.Copy(block, 0, res_arr, i, block.Length);
            }
 
            return Encoding.Default.GetString(res_arr);
        }
 
        public static string feistel_decrypt(string str, string key)
        {
            byte[] str_arr = Encoding.Default.GetBytes(str);
            byte[] key_arr = Encoding.Default.GetBytes(key);
            byte[] res_arr = new byte[str_arr.Length];
 
            for (int i = str_arr.Length - 8; i >= 0; i = i - 8)
            {
                byte[] block = new byte[8];
 
                for (int j = 9; j > 0; j--)
                {
                    Array.Copy(str_arr, i, block, 0, 8);
                    byte[] subblock_left_arr = new byte[4];
                    Array.Copy(block, subblock_left_arr, 4);
                    byte[] subblock_right_arr = new byte[4];
                    Array.Copy(block, 4, subblock_right_arr, 0, 4);
 
                    byte[] subblock_key_arr = new byte[4];
                    Array.Copy(key_arr, subblock_key_arr, 4);
                    subblock_key_arr = shift_key_left(key_arr, 0);
 
                    block = crypt_block(subblock_left_arr, subblock_right_arr, subblock_key_arr, false);
                }
 
                Array.Copy(str_arr, i, block, 0, 8);
                byte[] subblock_left_arr_l = new byte[4];
                Array.Copy(block, subblock_left_arr_l, 4);
                byte[] subblock_right_arr_l = new byte[4];
                Array.Copy(block, 4, subblock_right_arr_l, 0, 4);
 
                byte[] subblock_key_arr_l = new byte[4];
                Array.Copy(key_arr, subblock_key_arr_l, 4);
                subblock_key_arr_l = shift_key_left(key_arr, 9);
 
                block = crypt_block(subblock_left_arr_l, subblock_right_arr_l, subblock_key_arr_l, true);
 
 
                Array.Copy(block, 0, res_arr, i, block.Length);
            }
 
            return Encoding.Default.GetString(res_arr);
        }
 
        private static byte[] crypt_block(byte[] subblock_left_arr, byte[] subblock_right_arr, byte[] subblock_key_arr, bool isLast)
        {
            int subblock_left = BitConverter.ToInt32(subblock_left_arr, 0);
            int subblock_right = BitConverter.ToInt32(subblock_right_arr, 0);
            int subblock_key = BitConverter.ToInt32(subblock_key_arr, 0);
            //xor
            subblock_left = subblock_left ^ subblock_key;
 
            byte[] tmp = new byte[2];
            Array.Copy(subblock_left_arr, tmp, 2);
            Int16 left = BitConverter.ToInt16(tmp, 0);
            Int16 right = BitConverter.ToInt16(subblock_left_arr, 2);
 
            //xor
            subblock_right = f(left, right) ^ subblock_right;
 
            subblock_left_arr = BitConverter.GetBytes(subblock_left);
            subblock_right_arr = BitConverter.GetBytes(subblock_right);
 
            //l <---> r
            byte[] res_arr = new byte[8];
            if (!isLast)
            {
                Array.Copy(subblock_right_arr, res_arr, 4);
                Array.Copy(subblock_left_arr, 0, res_arr, 4, 4);
            }
            else
            {
                Array.Copy(subblock_left_arr, res_arr, 4);
                Array.Copy(subblock_right_arr, 0, res_arr, 4, 4);
            }
            return res_arr;
        }
 
        private static int f(Int16 left, Int16 right)
        {
            //left cyclic shift
            int tmp = left;
            int l = tmp << 7;
            int r = l >> 16;
            left = (Int16)(l + r);
 
            //right cyclic shift
            tmp = right;
            l = tmp >> 5;
            r = l << 11;//16-5
            left = (Int16)(l + r);
 
            //l <---> r
            int res = (int)r << 16;
            return res + l;
        }
 
        private static byte[] shift_key_left(byte[] key_arr, int i)
        {
            byte[] tmp = new byte[4];
            Array.Copy(key_arr, tmp, 4);
            int left = BitConverter.ToInt32(tmp, 0);
            Array.Copy(key_arr, 4, tmp, 0, 4);
            int right = BitConverter.ToInt32(tmp, 0);
 
            //left cyclic shift
            int l_l = left << (i*3);
            int r_l = left >> (32 - i*3);
 
            int l_r = right << (i*3);
            int r_r = right >> (32 - i * 3);
 
            left = l_l + r_r;
            right = l_r + r_l;
 
 
            byte[] res_arr = new byte[8];
            Array.Copy(BitConverter.GetBytes(left), res_arr, 4);
            Array.Copy(BitConverter.GetBytes(right), 0, res_arr, 4, 4);
 
            return res_arr;
        }
Тестовые данные:
C#
1
2
string st = "kugyujfjuyhdfytdrtsrefsjtdtydytd";
string key = "abcdefgh";
Миниатюры
Сеть Фейстеля, неправильно работает  
Изображения
 
1
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.03.2014, 19:40
Ответы с готовыми решениями:

Неправильно работает код
Пишу парсер.Вот кусочек кода : private void GetRGB(string Line, ColorRGB C_RGB, int Step, int X, int Y) { string...

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

Неправильно работает форма логина
Собственно вот код connectclass connnection = new connectclass(); DataTable datatable = connection.query(&quot;SELECT *...

6
11 / 10 / 1
Регистрация: 05.02.2012
Сообщений: 106
16.03.2014, 16:49  [ТС]
Я заметил, что при дешифровании я не так применяю раундовые ключи, а точнее:

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
 
        public static string feistel_decrypt(string str, string key)
        {
            byte[] str_arr = Encoding.Default.GetBytes(str);
            byte[] key_arr = Encoding.Default.GetBytes(key);
            byte[] res_arr = new byte[str_arr.Length];
 
            for (int i = str_arr.Length - 8; i >= 0; i = i - 8)
            {
                byte[] block = new byte[8];
 
                for (int j = 9; j > 0; j--)
                {
                    Array.Copy(str_arr, i, block, 0, 8);
                    byte[] subblock_left_arr = new byte[4];
                    Array.Copy(block, subblock_left_arr, 4);
                    byte[] subblock_right_arr = new byte[4];
                    Array.Copy(block, 4, subblock_right_arr, 0, 4);
 
                    byte[] subblock_key_arr = new byte[4];
                    Array.Copy(key_arr, subblock_key_arr, 4);
                    subblock_key_arr = shift_key_left(key_arr, 0);
                    
                    //false - т.к. не последний раунд
                    block = crypt_block(subblock_left_arr, subblock_right_arr, subblock_key_arr, false);
                }
 
                Array.Copy(str_arr, i, block, 0, 8);
                byte[] subblock_left_arr_l = new byte[4];
                Array.Copy(block, subblock_left_arr_l, 4);
                byte[] subblock_right_arr_l = new byte[4];
                Array.Copy(block, 4, subblock_right_arr_l, 0, 4);
 
                byte[] subblock_key_arr_l = new byte[4];
                Array.Copy(key_arr, subblock_key_arr_l, 4);
                subblock_key_arr_l = shift_key_left(key_arr, 9);//<------здесь по идее должен быть 0
                //т.к. раундовые ключи должны применяться в обратном порядке
 
                //true- т.к. последний раунд
                block = crypt_block(subblock_left_arr_l, subblock_right_arr_l, subblock_key_arr_l, true);
 
 
                Array.Copy(block, 0, res_arr, i, block.Length);
            }
 
            return Encoding.Default.GetString(res_arr);
        }
Но фишка в том, что часть блоков с этой "ошибкой" расшифровываются полностью, но, если её исправить, то расшифруется ещё меньше!

Добавлено через 53 минуты
Вот более сокращенная версия с комментариями:

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
public static string feistel_crypt(string str, string key)
        {
            byte[] str_arr = Encoding.Default.GetBytes(str);
            byte[] key_arr = Encoding.Default.GetBytes(key);
            byte[] res_arr = new byte[str_arr.Length];
 
            for (int i = 0; i < str_arr.Length; i = i + 8)
            {
                byte[] block = new byte[8];
 
                for (int j = 0; j < 10; j++)
                {
                    //создаем 2 подблока
                    Array.Copy(str_arr, i, block, 0, 8);
                    byte[] subblock_left_arr = new byte[4];
                    Array.Copy(block, subblock_left_arr, 4);
                    byte[] subblock_right_arr = new byte[4];
                    Array.Copy(block, 4, subblock_right_arr, 0, 4);
 
                    //создаем раундовый ключ
                    byte[] subblock_key_arr = new byte[4];
                    Array.Copy(key_arr, subblock_key_arr, 4);
                    subblock_key_arr = shift_key_left(key_arr, j);
 
                    if(j!=9) //если j = 9, то не надо поблоки менять местами
                        block = crypt_block(subblock_left_arr, subblock_right_arr, subblock_key_arr, false);
                    else
                        block = crypt_block(subblock_left_arr, subblock_right_arr, subblock_key_arr, true);
                }
                //скидываем блок в результирующий массив
                Array.Copy(block, 0, res_arr, i, block.Length);
            }
 
            return Encoding.Default.GetString(res_arr);
        }
 
        public static string feistel_decrypt(string str, string key)
        {
            byte[] str_arr = Encoding.Default.GetBytes(str);
            byte[] key_arr = Encoding.Default.GetBytes(key);
            byte[] res_arr = new byte[str_arr.Length];
 
            //начинаем с конца
            for (int i = str_arr.Length - 8; i >= 0; i = i - 8)
            {
                byte[] block = new byte[8];
                //применяем раундовые ключи в обратном порядке
                for (int j = 9; j >= 0; j--)
                {
                    //создаем 2 подблока
                    Array.Copy(str_arr, i, block, 0, 8);
                    byte[] subblock_left_arr = new byte[4];
                    Array.Copy(block, subblock_left_arr, 4);
                    byte[] subblock_right_arr = new byte[4];
                    Array.Copy(block, 4, subblock_right_arr, 0, 4);
 
                    //создаем раундовый ключ
                    byte[] subblock_key_arr = new byte[4];
                    Array.Copy(key_arr, subblock_key_arr, 4);
 
                    if (j != 0) //если j = 0, то не надо поблоки менять местами
                    {
                        subblock_key_arr = shift_key_left(key_arr, j);
                        block = crypt_block(subblock_left_arr, subblock_right_arr, subblock_key_arr, false);
                    }
                    else
                    {
                        subblock_key_arr = shift_key_left(key_arr, 9);//магия
                        block = crypt_block(subblock_left_arr, subblock_right_arr, subblock_key_arr, true);
                    }
                }
 
                Array.Copy(block, 0, res_arr, i, block.Length);
            }
 
            return Encoding.Default.GetString(res_arr);
        }
 
        private static byte[] crypt_block(byte[] subblock_left_arr, byte[] subblock_right_arr, byte[] subblock_key_arr, bool isLast)
        {
            int subblock_left = BitConverter.ToInt32(subblock_left_arr, 0);
            int subblock_right = BitConverter.ToInt32(subblock_right_arr, 0);
            int subblock_key = BitConverter.ToInt32(subblock_key_arr, 0);
            //xor
            subblock_left = subblock_left ^ subblock_key;
 
            byte[] tmp = new byte[2];
            Array.Copy(subblock_left_arr, tmp, 2);
            Int16 left = BitConverter.ToInt16(tmp, 0);
            Int16 right = BitConverter.ToInt16(subblock_left_arr, 2);
 
            //xor
            subblock_right = f(left, right) ^ subblock_right;
 
            subblock_left_arr = BitConverter.GetBytes(subblock_left);
            subblock_right_arr = BitConverter.GetBytes(subblock_right);
 
            //меняем или не меняем подблоки местами при объединении
            byte[] res_arr = new byte[8];
            if (!isLast)
            {
                Array.Copy(subblock_right_arr, res_arr, 4);
                Array.Copy(subblock_left_arr, 0, res_arr, 4, 4);
            }
            else
            {
                Array.Copy(subblock_left_arr, res_arr, 4);
                Array.Copy(subblock_right_arr, 0, res_arr, 4, 4);
            }
            return res_arr;
        }
 
        private static int f(Int16 left, Int16 right)
        {
            //циклический сдвиг влево на 7
            int tmp = left;
            int l = tmp << 7;
            int r = l >> 16;
            left = (Int16)(l + r);
 
            //циклический сдвиг вправо на 5
            tmp = right;
            l = tmp >> 5;
            r = l << 11;//16-5
            left = (Int16)(l + r);
 
            //меняем части местами
            int res = (int)r << 16;
            return res + l;
        }
 
        //возвращает интересующую нас левую половину ключа
        private static byte[] shift_key_left(byte[] key_arr, int i)
        {
            byte[] tmp = new byte[4];
            Array.Copy(key_arr, tmp, 4);
            int left = BitConverter.ToInt32(tmp, 0);
            Array.Copy(key_arr, 4, tmp, 0, 4);
            int right = BitConverter.ToInt32(tmp, 0);
 
            //циклический сдвиг влево на i * 3
            int l_l = left << (i * 3);
            int r_r = right >> (32 - i * 3);
            left = l_l + r_r;
 
            return BitConverter.GetBytes(left);
        }
0
11 / 10 / 1
Регистрация: 05.02.2012
Сообщений: 106
16.03.2014, 20:28  [ТС]
Разобрался) Там было несколько ошибок.
Вот результат:
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
//str - исходная строка, key - ключ (не менее 8 символов)
        public static string feistel_crypt(string str, string key)
        {
            if(key.Length < 8)
                throw new ArgumentException("Very small key! (min = 8 symbols)");
 
            byte[] str_arr = Encoding.Default.GetBytes(str);
            byte[] key_arr = Encoding.Default.GetBytes(key);
 
            //если длина не кратна 64 битам (8 байтам)
            int diff = str_arr.Length % 8;
            if (diff != 0)
            {
                byte[] temp = new byte[str_arr.Length + (8 - diff)];
                Array.Copy(str_arr, temp, str_arr.Length);
                str_arr = temp;
            }
 
            byte[] res_arr = new byte[str_arr.Length];
            //шифруем по блокам
            for (int i = 0; i < str_arr.Length; i = i + 8)
            {
                byte[] block = new byte[8];
                Array.Copy(str_arr, i, block, 0, 8);
 
                for (int j = 0; j <= 9; j++)
                {
                    //создаем 2 подблока
                    byte[] subblock_left_arr = new byte[4];
                    Array.Copy(block, subblock_left_arr, 4);
                    byte[] subblock_right_arr = new byte[4];
                    Array.Copy(block, 4, subblock_right_arr, 0, 4);
 
                    //создаем раундовый ключ
                    byte[] subblock_key_arr = new byte[4];
                    Array.Copy(key_arr, subblock_key_arr, 4);
                    subblock_key_arr = shift_key_left(key_arr, j);
 
                    if(j!=9)//если j = 9, то не надо поблоки менять местами
                        block = crypt_block(subblock_left_arr, subblock_right_arr, subblock_key_arr, false);
                    else
                        block = crypt_block(subblock_left_arr, subblock_right_arr, subblock_key_arr, true);
                }
                //скидываем блок в результирующий массив
                Array.Copy(block, 0, res_arr, i, block.Length);
            }
            return Encoding.Default.GetString(res_arr);
        }
 
        private static byte[] crypt_block(byte[] subblock_left_arr, byte[] subblock_right_arr, byte[] subblock_key_arr, bool isLast)
        {
            int subblock_left = BitConverter.ToInt32(subblock_left_arr, 0);
            int subblock_right = BitConverter.ToInt32(subblock_right_arr, 0);
            int subblock_key = BitConverter.ToInt32(subblock_key_arr, 0);
 
            //xor
            subblock_left = subblock_left ^ subblock_key;
            subblock_left_arr = BitConverter.GetBytes(subblock_left);
 
            byte[] tmp = new byte[2];
            Array.Copy(subblock_left_arr, tmp, 2);
            Int16 left = BitConverter.ToInt16(tmp, 0);
            Array.Copy(subblock_left_arr, 2, tmp, 0, 2);
            Int16 right = BitConverter.ToInt16(subblock_left_arr, 2);
 
            //xor
            subblock_right = f(left, right) ^ subblock_right;
            subblock_right_arr = BitConverter.GetBytes(subblock_right);
 
            //меняем или не меняем подблоки местами при объединении
            byte[] res_arr = new byte[8];
            if (!isLast)
            {
                Array.Copy(subblock_right_arr, res_arr, 4);
                Array.Copy(subblock_left_arr, 0, res_arr, 4, 4);
            }
            else
            {
                Array.Copy(subblock_left_arr, res_arr, 4);
                Array.Copy(subblock_right_arr, 0, res_arr, 4, 4);
            }
            return res_arr;
        }
 
        public static string feistel_decrypt(string str, string key)
        {
            if (key.Length < 8)
                throw new ArgumentException("Very small key! (min = 8 symbols)");
 
            byte[] str_arr = Encoding.Default.GetBytes(str);
            byte[] key_arr = Encoding.Default.GetBytes(key);
            byte[] res_arr = new byte[str_arr.Length];
 
            //если длина не кратна 64 битам (8 байтам)
            int diff = str_arr.Length % 8;
            if (diff != 0)
                throw new ArgumentException("Incorrect input string!");
            //начинаем с конца
            for (int i = str_arr.Length - 8; i >= 0; i = i - 8)
            {
                byte[] block = new byte[8];
                Array.Copy(str_arr, i, block, 0, 8);
                //применяем раундовые ключи в обратном порядке
                for (int j = 9; j >= 0; j--)
                {
                    //создаем 2 подблока
                    byte[] subblock_left_arr = new byte[4];
                    Array.Copy(block, subblock_left_arr, 4);
                    byte[] subblock_right_arr = new byte[4];
                    Array.Copy(block, 4, subblock_right_arr, 0, 4);
 
                    //создаем раундовый ключ
                    byte[] subblock_key_arr = new byte[4];
                    Array.Copy(key_arr, subblock_key_arr, 4);
                    subblock_key_arr = shift_key_left(key_arr, j);
 
                    if (j != 0)//если j = 0, то не надо поблоки менять местами
                        block = decrypt_block(subblock_left_arr, subblock_right_arr, subblock_key_arr, false);
                    else
                        block = decrypt_block(subblock_left_arr, subblock_right_arr, subblock_key_arr, true);
                }
                //скидываем блок в результирующий массив
                Array.Copy(block, 0, res_arr, i, block.Length);
            }
            return Encoding.Default.GetString(res_arr);
        }
 
        private static byte[] decrypt_block(byte[] subblock_left_arr, byte[] subblock_right_arr, byte[] subblock_key_arr, bool isLast)
        {
            int subblock_left = BitConverter.ToInt32(subblock_left_arr, 0);
            int subblock_right = BitConverter.ToInt32(subblock_right_arr, 0);
            int subblock_key = BitConverter.ToInt32(subblock_key_arr, 0);
 
            byte[] tmp = new byte[2];
            Array.Copy(subblock_left_arr, tmp, 2);
            Int16 left = BitConverter.ToInt16(tmp, 0);
            Array.Copy(subblock_left_arr, 2, tmp, 0, 2);
            Int16 right = BitConverter.ToInt16(subblock_left_arr, 2);
 
            //xor
            subblock_right = f(left, right) ^ subblock_right;
 
            //xor
            subblock_left = subblock_left ^ subblock_key;
            subblock_left_arr = BitConverter.GetBytes(subblock_left);
 
            subblock_right_arr = BitConverter.GetBytes(subblock_right);
 
            //меняем или не меняем подблоки местами при объединении
            byte[] res_arr = new byte[8];
            if (!isLast)
            {
                Array.Copy(subblock_right_arr, res_arr, 4);
                Array.Copy(subblock_left_arr, 0, res_arr, 4, 4);
            }
            else
            {
                Array.Copy(subblock_left_arr, res_arr, 4);
                Array.Copy(subblock_right_arr, 0, res_arr, 4, 4);
            }
            return res_arr;
        }
 
        private static int f(Int16 left, Int16 right)
        {
            //циклический сдвиг влево на 7
            int l = left << 7;
            int r = l >> 16;
            left = (Int16)(l + r);
 
            //циклический сдвиг вправо на 5
            l = right >> 5;
            r = l << 11;//16-5
            right = (Int16)(l + r);
 
            //меняем части местами
            int res = (int)left << 16;
            return res + right;
        }
 
        //возвращает интересующую нас левую половину ключа
        private static byte[] shift_key_left(byte[] key_arr, int i)
        {
            byte[] tmp = new byte[4];
            Array.Copy(key_arr, tmp, 4);
            int left = BitConverter.ToInt32(tmp, 0);
            Array.Copy(key_arr, 4, tmp, 0, 4);
            int right = BitConverter.ToInt32(tmp, 0);
 
            //циклический сдвиг влево на i * 3
            int l_l = left << (i * 3);
            int r_r = right >> (32 - i * 3);
            left = l_l + r_r;
 
            return BitConverter.GetBytes(left);
        }
Изображения
 
5
2 / 2 / 2
Регистрация: 18.03.2012
Сообщений: 253
19.05.2014, 20:15
Есть небольшой вопрос, касательно ключа. В теории сеть Фейстеля подразумевает делении входящего сообщения, на блоки по Н-бит , которые в свою очередь, делятся на правую и левую части. У вас для каждого блока один ключ, или нет? Никак не могу понять, как он генерируется для каждой части.
0
11 / 10 / 1
Регистрация: 05.02.2012
Сообщений: 106
22.05.2014, 00:43  [ТС]
Мы пользуемся циклическим сдвигом для изменения ключа для разных блоков) Там есть как раз такой метод в конце.
0
2 / 2 / 0
Регистрация: 07.06.2013
Сообщений: 80
14.01.2015, 18:01
VV_RIP, есть исходники?
0
 Аватар для N1x0n
16 / 16 / 3
Регистрация: 14.04.2015
Сообщений: 155
Записей в блоге: 1
27.10.2019, 00:11
Не подскажите, как переделать под такой вариант?
Миниатюры
Сеть Фейстеля, неправильно работает  
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.10.2019, 00:11
Помогаю со студенческими работами здесь

Неправильно работает авторизация на сайте
Добрый вечер. Помогите с авторизацией на сайте, есть несколько аккаунтов идет проверка каждого на авторизацию в ЛК на сайте. Знаю что код...

Неправильно работает Scroll и DragDrop в ListBoxDragDropTarget
Когда ListBoxDragDropTarget находится в TreeView, а TreeView находится ScrollViewer, неверно отрабатывает Drag и прокрутка косесом мыши...

Цикл работает неправильно, в то время как POST работает
Всем привет! Я хотел написать под php скрипт с авторизацией, брут, на своем сайте(подбор пароля). Написал код на загрузку словаря +...

Программа работает, но неправильно
Определить новые версии классов ResearchTeam и ResearchTeamCollection&lt;TKey&gt;. Новая версия класса ResearchTeam реализует интерфейс...

Неправильно работает программа
Может что-то нужно дописать в мэйн? using System; using System.Collections; using System.Collections.Generic; using...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru