Шифрование DES - теория и практика
Ключ K(i), определяемый на каждом шаге итерации, есть результат выбора определе н ных бит из 56-битовой последовательности C(i)D(i) и их перестановки. Другими словами, K(i) = K(C(i)D(i)), где функция K определяется данными, приведенными в таблице.
"Функция перестановки и выбора K"(перестановка со сжатием)
После сдвига выбирается 48 из 56. Так как при этом не только выбирается подмножество битов, но и изменяется их порядок, эта операция называется перестановка со сжатием. Её р е зультатом является набор из 48 битов.
14
17
11
24
1
5
3
28
15
6
21
10
23
19
12
4
26
8
16
7
27
20
13
2
41
52
31
37
47
55
30
40
51
45
33
48
44
49
39
56
34
53
46
42
50
36
29
32
Как следует из таблицы первый бит K(i) - это бит 14 последовательности C(i)D(i), второй - бит 17, последний - бит 32.
Пример
Шифруемое сообщение - шифровка = 11111000 11101000 11110100 11110000 11101110 11100010 11101010 11100000
Ключ шифрования 12345678 = 00110001 00110010 00110011 00110100 00110101 00110110 00110111 00111000
Шаг 1 Начальная перестановка
Входная последовательность
1111100011101000111101001111000011101110111000101110101011100000 - согласно таблице начальной перестановки перестанавливаем биты в сообщении.
58
50
42
34
26
18
10
2
60
52
44
36
28
20
12
4
62
54
46
38
30
22
14
6
64
56
48
40
32
24
16
8
57
49
41
33
25
17
9
1
59
51
43
35
27
19
11
3
61
53
45
37
29
21
13
5
63
55
47
39
31
23
15
7
Полученная последовательность 1111111100001101000101000000000011111111111111110101001101110000
Шаг 2 Получение последовательности L(0) и R(0)
Делим полученную последовательность согласно таблицам.
Последовательности получаются путём деления блока в 64 бита на 2 равных части.
L(0) перестановка
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
L (0) последовательность полученная 11111111000011010001010000000000
R(0) перестановка
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
R (0) последовательность полученная 11111111111111110101001101110000
Шаг 3 Функция выбора и перестановки последовательности В (преобразование ключа шифрования)
Входная последовательность
0011000100110010001100110011010000110101001101100011011100111000
57
49
41
33
25
17
9
1
58
50
42
34
26
18
10
2
59
51
43
35
27
19
11
3
60
52
44
36
63
55
47
39
31
23
15
7
62
54
46
38
30
22
14
6
61
53
45
37
29
21
13
5
28
20
12
4
Полученная последовательность 00000000000000001111111111110110011001111000100000001111
Шаг 4 Получение последовательностей C(0) D(0)
Полученную последовательность(ключа) делим на две согласно таблицам.
C(0)
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
Последовательность C(0) = 0000000000000000111111111111
D(0)
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
Последовательность D(0) = 0110011001111000100000001111
Шаг 5 получение последовательности C(i)
По таблице сдвигаем биты в последовательностях
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
1
2
2
2
2
2
2
1
2
2
2
2
2
2
1
C(0) = 0000000000000000111111111111
C(1)
0000000000000001111111111110
C(2)
0000000000000011111111111100
C(3)
0000000000001111111111110000
C(4)
0000000000111111111111000000
C(5)
0000000011111111111100000000
C(6)
0000001111111111110000000000
C(7)
0000111111111111000000000000
C(8)
0011111111111100000000000000
C(9)
0111111111111000000000000000
C(10)
1111111111100000000000000001
C(11)
1111111110000000000000000111
C(12)
1111111000000000000000011111
C(13)
1111100000000000000001111111
C(14)
1110000000000000000111111111
C(15)
1000000000000000011111111111
C(16)
0000000000000000111111111111
Шаг 6 получение последовательности D(i)
По той же таблице сдвигаем биты в последовательностях
D(0) = 0110011001111000100000001111
D(1)
1100110011110001000000011110
D(2)
1001100111100010000000111101
D(3)
0110011110001000000011110110
D(4)
1001111000100000001111011001
D(5)
0111100010000000111101100110
D(6)
1110001000000011110110011001
D(7)
1000100000001111011001100111
D(8)
0010000000111101100110011110
D(9)
0100000001111011001100111100
D(10)
0000000111101100110011110001
D(11)
0000011110110011001111000100
D(12)
0001111011001100111100010000
D(13)
0111101100110011110001000000
D(14)
1110110011001111000100000001
D(15)
1011001100111100010000000111
D(16)
0110011001111000100000001111
Шаг 7 получение последовательностей K(i)
14
17
11
24
1
5
3
28
15
6
21
10
23
19
12
4
26
8
16
7
27
20
13
2
41
52
31
37
47
55
30
40
51
45
33
48
44
49
39
56
34
53
46
42
50
36
29
32
Для получения последовательности K(i) произведём конкатенацию последовательностей C(i) и D(i). В полученной последовательности C(i)D(i) переставим биты согласно таблице.
K(0) = 010100010010110010001100101001110100001111000000
K(1)
010100000010110010101100010101110010101011000010
K(2)
010100001010110010100100010100001010001101000111
K(3)
110100001010110000100110111101101000010010001100
K(4)
111000001010011000100110010010000011011111001011
K(5)
111000001001011000100110001111101111000000101001
K(6)
111000001001001001110010011000100101110101100010
K(7)
101001001101001001110010100011001010100100111010
K(8)
101001100101001101010010111001010101111001010000
K(9)
001001100101001101010011110010111001101001000000
K(10)
001011110101000101010001110100001100011100111100
K(11)
000011110100000111011001000110010001111010001100
K(12)
000111110100000110011001110110000111000010110001
K(13)
000111110000100110001001001000110110101000101101
K(14)
000110110010100010001101101100100011100110010010
K(15)
000110010010110010001100101001010000001100110111
K(16)
010100010010110010001100101001110100001111000000
Шаг 8 функция Е(шифрование, перестановка с расширением)
По таблице преобразовать последовательности R(i)
32
1
2
3
4
5
4
5
6
7
8
9
8
9
10
11
12
13
12
13
14
15
16
17
13
17
18
19
20
21
20
21
22
23
24
25
24
25
26
27
28
29
28
29
30
31
32
1
R(0) = 11111111111111110101001101110000
E(R(0)) = 011111111111111111111110101010100110101110100001
Объединение R(i)K(i+1) XOR
R(0)K(1) xor = 001011111101001101010010111111010100000101100011
Подстановка через S блоки(вход 6 бит выход 4 бита)
S(1) = 2 = 0010 S(2) = 14 = 1110 S(3) = 9 = 1001 S(4) = 2 = 0010
S(5) = 3 = 0011 S(6) = 3 = 0011 S(7) = 11 = 1011 S(8) = 1 = 0001
Выходная (S1..S8) = 00101110100100100011001110110001
Прямая перестановка с помощью P блоков
16
7
20
21
29
12
28
17
1
15
23
26
5
18
31
10
2
8
24
14
32
27
3
9
19
13
30
6
22
11
4
25
Результат = 01100110011010000010111110010001
L(i)R(i+1) XOR
L(0) = 11111111000011010001010000000000
R( 0 ) = 01100110011010000010111110010001
XOR R(1)=10011001011001010011101110010001
L(1) = R(0)
В итоге этих действий появляется новая правая половина, а старая правая половина становится новой левой. Эти действия повторяются 16 раз, образуя 16 этапов DES .
L(1) = 11111111111111110101001101110000
R(1) = 10011001011001010011101110010001
E(R1) = 110011110010101100001010100111110111110010100011
R(1) XOR K(2) = 100111111000011110101110110011111101111111100100
S(1..8) = 00101001100011011111100011000100
P = 10110001000111000101001111100001
R(1) XOR L(1) = 01001110111000110000000010010001 = R(2)
L(2) = R(1) = 10011001011001010011101110010001
E(R2) = 101001011101011100000110100000000001010010100010
R(2) XOR K(3) = 011101010111101100100000011101101001000000101110
S(1..8) = 00111010001110101000100101000010
P = 01010101010110100010001001000110
R(2) XOR L(2) = 11001100001111110001100111010111 = R(3)
L(3) = R(2) = 01001110111000110000000010010001
E(R3) = 111001011000000111111110100011110011111010101111
R(3) XOR K(4) = 000001010010011111011000110001110000100101100100
S(1..8) = 00000111000110110110011111010100
P = 11000110011101000110000011111001
R(3) XOR L(3) = 10001000100101110110000001101000 = R(4)
L(4) = R(3) = 11001100001111110001100111010111
E(R4) = 010001010001010010101110101100000000001101010001
R(4) XOR K(5) = 101001011000001010001000100011101111001101111000
S(1..8) = 01001100001100001000101000011100
P = 00011111001010001000000000110100
R(4) XOR L(4) = 11010011000101111001100111100011 = R(5)
L(5) = R(4) = 10001000100101110110000001101000
E(R5) = 111010100110100010101111110011110011111100000111
R(5) XOR K(6) = 000010101111101011011101101011010110001001100101
S(1..8) = 01000010100111101110010001001110
P = 01001101010101101001000111101000
R(5) XOR L(5) = 11000101110000011111000110000000 = R(6)
L(6) = R(5) = 11010011000101111001100111100011
E(R6) = 011000001011111000000011111110100011110000000001
R(6) XOR K(7) = 110001000110110001110001011101101001010100111011
S(1..8) = 01011110010010011000100110010101
P = 11010011000010011010100001110011
R(6) XOR L(6) = 00000000000111100011000110010000 = R(7)
L(7) = R(6) = 11000101110000011111000110000000
E(R7) = 000000000000000011111100000110100011110010100000
R(7) XOR K(8) = 101001100101001110101110111111110110001011110000
S(1..8) = 01001010010111110011101010010000
P = 11110110011010011001000011000001
R(7) XOR L(7) = 00110011101010000110000101000001 = R(8)
L(8) = R(7) = 00000000000111100011000110010000
E(R8) = 100110100111110101010000001100000010101000000010
R(8) XOR K(9) = 101111000010111000000011111110111011000001000010
S(1..8) = 01110001010110001110000010110010
P = 00000111000001111100011011000011
R(8) XOR L(8) = 00000111000110011111011101010011 = R(9)
L(9) = R(8) = 00110011101010000110000101000001
E(R9) = 100000001110100011110011111110101110101010100110
R(9) XOR K(10) = 101011111011100110100010001010100010110110011010
S(1..8) = 10010101100101101010111010000000
P = 00010101111000000101000110011011
R(9) XOR L(9) = 00100110010010000011000011011010 = R(10)
L(10) = R(9) = 00000111000110011111011101010011
E(R10) = 000100001100001001010000000110100001011011110100
R(10) XOR K(11) = 000111111000001110001001000000110000100001111000
S(1..8) = 01001001010101100010011101101111
P = 00001100011110111111110010101000
R(10) XOR L(10) = 00001011011000100000101111111011 = R(11)
L(11) = R(10) = 00100110010010000011000011011010
E(R11) = 100001010110101100000100000001010111111111110110
R(11) XOR K(12) = 100110100010101010011101110111010000111101000111
S(1..8) = 10001110111111101001000000111000
P = 01101111110010010001010101010100
R(11) XOR L(11) = 01001001100000010010010110001110 = R(12)
L(12) = R(11) = 00001011011000100000101111111011
E(R12) = 001001010011110000000010100100001011110001011100
R(12) XOR K(13) = 001110100011010110001011101100111101011001110001
S(1..8) = 10001000011111110111100000101111
P = 10111100110011110001110011100100
R(12) XOR L(12) = 10110111101011010001011100011111 = R(13)
L(13) = R(12) = 01001001100000010010010110001110
E(R13) = 110110101111110101011010100010101110100011111111
R(13) XOR K(14) = 110000011101010111010111001110001101000101101101
S(1..8) = 11111011111011000110100110111000
P = 01011010100011011111011111000111
R(13) XOR L(13) = 00010011000011001101001001001001 = R(14)
L(14) = R(13) = 10110111101011010001011100011111
E(R14) = 100010100110100001011001011010100100001001010010
R(14) XOR K(15) = 100100110100010011010101110011110100000101100101
S(1..8) = 11101100100000101111010010111110
P = 00101011110011101000011110111001
R(14) XOR L(14) = 10011100011000111001000010100110 = R(15)
L(15) = R(14) = 00010011000011001101001001001001
E(R15) = 010011111000001100000111110010100001010100001101
R(15) XOR K(16) = 000111101010111110001011011011010101011011001101
S(1..8) = 01000100011111111001110111110111
P = 10110111010100111011110001111101
R(15) XOR L(15) = 10100100010111110110111000110100 = R(16)
L(16) = R(15) = 10011100011000111001000010100110
Шаг 9 заключительная перестановка(обратная)
40
8
48
16
56
24
64
32
39
7
47
15
55
23
63
31
38
6
46
14
54
22
62
30
37
5
45
13
53
21
61
29
36
4
44
12
52
20
60
28
35
3
43
11
51
19
59
27
34
2
42
10
50
18
58
26
33
1
41
9
49
17
57
25
Вход (L16R16) = 1001110001100011100100001010011010100100010111110110111000110100
Полученная = 00110000 00111001 11101011 01101000 01100110 10011011 00111000 11000101 =
48 57 235 104 102 155 56 197 = 0 9 л h f > 8 Е
Программа
Шифрование
Расшифровка
Текст программы
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Memo2: TMemo;
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Button2: TButton;
Memo3: TMemo;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
c, d, k: array [0..16] of AnsiString;
r, l, rez, z: AnsiString;
w, desK, desR: byte;
implementation
{$R *.dfm}
procedure DecToBin(input: string; var output: ansistring);
var
a, b: double;
ost, q, w: byte;
st: AnsiString;
str: string[8];
begin
str:= ' ';
for w:= 1 to 8 do
begin
q:= Ord(input[w]);
b:= q;
While b <> 1 do
begin
a:= q / 2;
b:= Int(a);
if a = b then
ost:= 0
else ost:= 1;
q:= Round(b);
st:= st + IntToStr(ost);
if b = 1 then st:= st + '1';
end;
ost:= 1;
for q:= Length(st) downto 1 do // ia?aai?io no?iee
begin
str[ost]:= st[q];
Inc(ost);
end;
case Length(st) of
1: Insert('0000000', str, 1); // aiaaaeaiea iaainoa?ueo iieae
2: Insert('000000', str, 1);
3: Insert('00000', str, 1);
4: Insert('0000', str, 1);
5: Insert('000', str, 1);
6: Insert('00', str, 1);
7: Insert('0', str, 1);
end;
output:= output + str;// + ' ';
str:= ' ';
st:= '';
end;
end;
procedure BeginPerestanovka(input: ansistring; var output: ansistring);
begin
output:=
input[58] + input[50] + input[42] + input[34] + input[26] + input[18]
+ input[10] + input[2]
+ input[60] + input[52] + input[44] + input[36] + input[28] + input[20]
+ input[12] + input[4]
+ input[62] + input[54] + input[46] + input[38] + input[30] + input[22]
+ input[14] + input[6]
+ input[64] + input[56] + input[48] + input[40] + input[32] + input[24]
+ input[16] + input[8]
+ input[57] + input[49] + input[41] + input[33] + input[25] + input[17]
+ input[9] + input[1]
+ input[59] + input[51] + input[43] + input[35] + input[27] + input[19]
+ input[11] + input[3]
+ input[61] + input[53] + input[45] + input[37] + input[29] + input[21]
+ input[13] + input[5]
+ input[63] + input[55] + input[47] + input[39] + input[31] + input[23]
+ input[15] + input[7];
end;
procedure PerestanovkaKeyB(input: AnsiString; var output: AnsiString);
begin
output:= '';
output:=
input[57]+input[49]+input[41]+input[33]+input[25]+input[17]+input[9]
+input[1]+input[58]+input[50]+input[42]+input[34]+input[26]+input[18]
+input[10]+input[2]+input[59]+input[51]+input[43]+input[35]+input[27]
+input[19]+input[11]+input[3]+input[60]+input[52]+input[44]+input[36]
+input[63]+input[55]+input[47]+input[39]+input[31]+input[23]+input[15]
+input[7]+input[62]+input[54]+input[46]+input[38]+input[30]+input[22]
+input[14]+input[6]+input[61]+input[53]+input[45]+input[37]+input[29]
+input[21]+input[13]+input[5]+input[28]+input[20]+input[12]+input[4];
end;
procedure pocledovatelnostiK;
var
w: byte;
bufer: AnsiString;
begin
for w:= 0 to 16 do
begin
bufer:= Concat(c[w], d[w]);
k[w]:=
Concat(bufer[14], bufer[17], bufer[11], bufer[24], bufer[1], bufer[5],
bufer[3], bufer[28], bufer[15], bufer[6], bufer[21], bufer[10],
bufer[23], bufer[19], bufer[12], bufer[4], bufer[26], bufer[8],
bufer[16], bufer[7], bufer[27], bufer[20], bufer[13], bufer[2],
bufer[41], bufer[52], bufer[31], bufer[37], bufer[47], bufer[55],
bufer[30], bufer[40], bufer[51], bufer[45], bufer[33], bufer[48],
bufer[44], bufer[49], bufer[39], bufer[56], bufer[34], bufer[53],
bufer[46], bufer[42], bufer[50], bufer[36], bufer[29], bufer[32]);
end;
end;
procedure FuncE;
const
s1 : array[0..3, 0..15] of string[4] =
(('1110','0100','1101','0001','0010','1111','1011','1000','0011','1010','0110','1100','0101','1001','0000','0111'),
('0000','1111','0111','0100','1110','0010','1101','0001','1010','0110','1100','1011','1001','0101','0011','1000'),
('0100','0001','1110','1000','1001','0110','0010','1011','1111','1100','1001','0111','0011','1010','0101','0000'),
('1111','1100','1000','0010','0100','1001','0001','0111','0101','1011','0011','1110','1010','0000','1001','1101'));
s2 : array[0..3, 0..15] of string[4] =
(('1111','0001','1000','1110','0110','1011','0011','0100','1001','0111','0010','1101','1100','0000','0101','1010'),
('0011','1101','0100','0111','1111','0010','1000','1110','1100','0000','0001','1010','0110','1001','1011','0101'),
('0000','1110','0111','1011','1010','0100','1101','0001','0101','1000','1100','0110','1001','0011','0010','1111'),
('1101','1000','1010','0001','0011','1111','0100','0010','1011','0110','0111','1100','0000','0101','1110','1001'));
s3 : array [0..3, 0..15] of string[4] =
(('1010','0000','1001','1110','0110','0011','1111','0101','0001','1101','1100','0111','1011','0100','0010','1000'),
('1101','0111','0000','1001','0011','0100','0110','1010','0010','1000','0101','1110','1100','1011','1111','0001'),
('1101','0110','0100','1001','1000','1111','0011','0000','1011','0001','0010','1100','0101','1010','1110','0111'),
('0001','1010','1101','0000','0110','1001','1000','0111','0100','1111','1110','0011','1011','0101','0010','1100'));
s4 : array [0..3, 0..15] of string[4] =
(('0111','1101','1110','0011','0000','0110','1001','1010','0001','0010','1000','0101','1011','1100','0100','1111'),
('1101','1000','1011','0101','0110','1111','0000','0011','0100','0111','0010','1100','0001','1010','1110','1001'),
('1010','0110','1001','0000','1100','1011','0111','1101','1111','0001','0011','1110','0101','0010','1000','0100'),
('0011','1111','0000','0110','1010','0001','1101','1000','1001','0100','0101','1011','1100','0111','0010','1110'));
s5 : array [0..3, 0..15] of string[4] =
(('0010','1100','0100','0001','0111','1010','1011','0110','1000','0101','0011','1111','1101','0000','1110','1001'),
('1110','1011','0010','1100','0100','0111','1101','0001','0101','0000','1111','1010','0011','1001','1000','0110'),
('0100','0010','0001','1011','1010','1101','0111','1000','1111','1001','1100','0101','0110','0011','0000','1110'),
('1011','1000','1100','0111','0001','1110','0010','1101','0110','1111','0000','1001','1010','0100','0101','0011'));
s6 : array [0..3, 0..15] of string[4] =
(('1100','0001','1010','1111','1001','0010','0110','1000','0000','1101','0011','0100','1110','0111','0101','1011'),
('1010','1111','0100','0010','0111','1100','1001','0101','0110','0001','1101','1110','0000','1011','0011','1000'),
('1001','1110','1111','0101','0010','1000','1100','0011','0111','0000','0100','1010','0001','1101','1011','0110'),
('0100','0011','0010','1100','1001','0101','1111','1010','1011','1110','0001','0111','0110','0000','1000','1101'));
s7 : array [0..3, 0..15] of string[4] =
(('0100','1011','0010','1110','1111','0000','1000','1101','0011','1100','1001','0111','0101','1010','0110','0001'),
('1101','0000','1011','0111','0100','1001','0001','1010','1110','0011','0101','1100','0011','1111','1000','0110'),
('0001','0100','1011','1101','1100','0011','0111','1110','1010','1111','0110','1000','0000','0101','1001','0010'),
('0110','1011','1101','1000','0001','0100','1010','0111','1001','0101','0000','1111','1110','0010','0011','1100'));
s8 : array [0..3, 0..15] of string[4] =
(('1101','0010','1000','0100','0110','1111','1011','0001','1010','1001','0011','1110','0101','0000','1100','0111'),
('0001','1111','1101','1000','1010','0011','0111','0100','1100','0101','0110','1011','0000','1110','1001','0011'),
('0111','1011','0100','0001','1001','1100','1110','0010','0000','0110','1010','1101','1111','0011','0101','1000'),
('0010','0001','1110','0111','0100','1010','1000','1101','1111','1100','1001','0000','0011','0101','0110','1011'));
var
_1, _2: AnsiString;
p: string[6];
v, b, x, a, j: byte;
u: string[2];
o: string[4];
function s(var a, b: byte): byte;
begin
if u = '00' then a:= 0
else if u = '01' then a:= 1
else if u = '10' then a:= 2
else if u = '11' then a:= 3;
if o = '0000' then b:= 0
else if o = '0001' then b:= 1
else if o = '0010' then b:= 2
else if o = '0011' then b:= 3
else if o = '0100' then b:= 4
else if o = '0101' then b:= 5
else if o = '0110' then b:= 6
else if o = '0111' then b:= 7
else if o = '1000' then b:= 8
else if o = '1001' then b:= 9
else if o = '1010' then b:= 10
else if o = '1011' then b:= 11
else if o = '1100' then b:= 12
else if o = '1101' then b:= 13
else if o = '1110' then b:= 14
else if o = '1111' then b:= 15;
end;
begin
for a:= 1 to 16 do
begin
z:= Concat(r[32],r[1],r[2],r[3],r[4],r[5],r[4],r[5],r[6],r[7],r[8],r[9],
r[8],r[9],r[10],r[11],r[12],r[13],r[12],r[13],r[14],r[15],r[16],r[17],
r[16],r[17],r[18],r[19],r[20],r[21],r[20],r[21],r[21],r[23],r[24],r[25],
r[24],r[25],r[26],r[27],r[28],r[29],r[28],r[29],r[30],r[31],r[32],r[1]);
_1:= k[a];
r:= z;
for j:= 1 to 48 do // xor
begin
v:= StrToInt(r[j]);
b:= StrToInt(_1[j]);
x:= v xor b;
_2:= Concat(_2, IntToStr(x));
end;
p:= Copy(_2, 1, 6); u:= p[1] + p[6]; o:= Copy(p, 2, 5); s(v, b);
rez:= rez + s1[v, b];
p:= Copy(_2, 7, 12); u:= p[1] + p[6]; o:= Copy(p, 2, 5); s(v, b);
rez:= rez + s2[v, b];
p:= Copy(_2, 13, 18); u:= p[1] + p[6]; o:= Copy(p, 2, 5); s(v, b);
rez:= rez + s3[v, b];
p:= Copy(_2, 19, 24); u:= p[1] + p[6]; o:= Copy(p, 2, 5); s(v, b);
rez:= rez + s4[v, b];
p:= Copy(_2, 25, 30); u:= p[1] + p[6]; o:= Copy(p, 2, 5); s(v, b);
rez:= rez + s5[v, b];
p:= Copy(_2, 31, 36); u:= p[1] + p[6]; o:= Copy(p, 2, 5); s(v, b);
rez:= rez + s6[v, b];
p:= Copy(_2, 37, 42); u:= p[1] + p[6]; o:= Copy(p, 2, 5); s(v, b);
rez:= rez + s7[v, b];
p:= Copy(_2, 43, 48); u:= p[1] + p[6]; o:= Copy(p, 2, 5); s(v, b);
rez:= rez + s8[v, b];
// ? ia?anoaiiaea
_2:= rez;
rez:= Concat(_2[16], _2[7], _2[20], _2[21], _2[29], _2[12], _2[28], _2[17],
_2[1], _2[15], _2[23], _2[26], _2[5], _2[18], _2[31], _2[10],
_2[2], _2[8], _2[24], _2[14], _2[32], _2[27], _2[3], _2[9],
_2[19], _2[13], _2[30], _2[6], _2[22], _2[11], _2[4], _2[25]);
for w:= 1 to 32 do
begin
v:= StrToInt(r[w]);
b:= StrToInt(l[w]);
x:= v xor b;
_2:= Concat(_2, IntToStr(x));
end;
l:= r;
r:= _2;
end;
_2:= Concat(l, r);
rez:= Concat(
_2[40], _2[8], _2[48], _2[16], _2[56], _2[24], _2[64], _2[32],
_2[39], _2[7], _2[47], _2[15], _2[55], _2[23], _2[63], _2[31],
_2[38], _2[6], _2[46], _2[14], _2[54], _2[22], _2[62], _2[30],
_2[37], _2[5], _2[45], _2[13], _2[53], _2[21], _2[61], _2[29],
_2[36], _2[4], _2[44], _2[12], _2[52], _2[20], _2[60], _2[28],
_2[35], _2[3], _2[43], _2[11], _2[51], _2[19], _2[59], _2[27],
_2[34], _2[2], _2[42], _2[10], _2[50], _2[18], _2[58], _2[26],
_2[33], _2[1], _2[41], _2[9], _2[49], _2[17], _2[57], _2[25]);
end;
procedure FuncER;
const
s1 : array[0..3, 0..15] of string[4] =
(('1110','0100','1101','0001','0010','1111','1011','1000','0011','1010','0110','1100','0101','1001','0000','0111'),
('0000','1111','0111','0100','1110','0010','1101','0001','1010','0110','1100','1011','1001','0101','0011','1000'),
('0100','0001','1110','1000','1001','0110','0010','1011','1111','1100','1001','0111','0011','1010','0101','0000'),
('1111','1100','1000','0010','0100','1001','0001','0111','0101','1011','0011','1110','1010','0000','1001','1101'));
s2 : array[0..3, 0..15] of string[4] =
(('1111','0001','1000','1110','0110','1011','0011','0100','1001','0111','0010','1101','1100','0000','0101','1010'),
('0011','1101','0100','0111','1111','0010','1000','1110','1100','0000','0001','1010','0110','1001','1011','0101'),
('0000','1110','0111','1011','1010','0100','1101','0001','0101','1000','1100','0110','1001','0011','0010','1111'),
('1101','1000','1010','0001','0011','1111','0100','0010','1011','0110','0111','1100','0000','0101','1110','1001'));
s3 : array [0..3, 0..15] of string[4] =
(('1010','0000','1001','1110','0110','0011','1111','0101','0001','1101','1100','0111','1011','0100','0010','1000'),
('1101','0111','0000','1001','0011','0100','0110','1010','0010','1000','0101','1110','1100','1011','1111','0001'),
('1101','0110','0100','1001','1000','1111','0011','0000','1011','0001','0010','1100','0101','1010','1110','0111'),
('0001','1010','1101','0000','0110','1001','1000','0111','0100','1111','1110','0011','1011','0101','0010','1100'));
s4 : array [0..3, 0..15] of string[4] =
(('0111','1101','1110','0011','0000','0110','1001','1010','0001','0010','1000','0101','1011','1100','0100','1111'),
('1101','1000','1011','0101','0110','1111','0000','0011','0100','0111','0010','1100','0001','1010','1110','1001'),
('1010','0110','1001','0000','1100','1011','0111','1101','1111','0001','0011','1110','0101','0010','1000','0100'),
('0011','1111','0000','0110','1010','0001','1101','1000','1001','0100','0101','1011','1100','0111','0010','1110'));
s5 : array [0..3, 0..15] of string[4] =
(('0010','1100','0100','0001','0111','1010','1011','0110','1000','0101','0011','1111','1101','0000','1110','1001'),
('1110','1011','0010','1100','0100','0111','1101','0001','0101','0000','1111','1010','0011','1001','1000','0110'),
('0100','0010','0001','1011','1010','1101','0111','1000','1111','1001','1100','0101','0110','0011','0000','1110'),
('1011','1000','1100','0111','0001','1110','0010','1101','0110','1111','0000','1001','1010','0100','0101','0011'));
s6 : array [0..3, 0..15] of string[4] =
(('1100','0001','1010','1111','1001','0010','0110','1000','0000','1101','0011','0100','1110','0111','0101','1011'),
('1010','1111','0100','0010','0111','1100','1001','0101','0110','0001','1101','1110','0000','1011','0011','1000'),
('1001','1110','1111','0101','0010','1000','1100','0011','0111','0000','0100','1010','0001','1101','1011','0110'),
('0100','0011','0010','1100','1001','0101','1111','1010','1011','1110','0001','0111','0110','0000','1000','1101'));
s7 : array [0..3, 0..15] of string[4] =
(('0100','1011','0010','1110','1111','0000','1000','1101','0011','1100','1001','0111','0101','1010','0110','0001'),
('1101','0000','1011','0111','0100','1001','0001','1010','1110','0011','0101','1100','0011','1111','1000','0110'),
('0001','0100','1011','1101','1100','0011','0111','1110','1010','1111','0110','1000','0000','0101','1001','0010'),
('0110','1011','1101','1000','0001','0100','1010','0111','1001','0101','0000','1111','1110','0010','0011','1100'));
s8 : array [0..3, 0..15] of string[4] =
(('1101','0010','1000','0100','0110','1111','1011','0001','1010','1001','0011','1110','0101','0000','1100','0111'),
('0001','1111','1101','1000','1010','0011','0111','0100','1100','0101','0110','1011','0000','1110','1001','0011'),
('0111','1011','0100','0001','1001','1100','1110','0010','0000','0110','1010','1101','1111','0011','0101','1000'),
('0010','0001','1110','0111','0100','1010','1000','1101','1111','1100','1001','0000','0011','0101','0110','1011'));
var
_1, _2: AnsiString;
p: string[6];
v, b, x, a, j: byte;
u: string[2];
o: string[4];
function s(var a, b: byte): byte;
begin
if u = '00' then a:= 0
else if u = '01' then a:= 1
else if u = '10' then a:= 2
else if u = '11' then a:= 3;
if o = '0000' then b:= 0
else if o = '0001' then b:= 1
else if o = '0010' then b:= 2
else if o = '0011' then b:= 3
else if o = '0100' then b:= 4
else if o = '0101' then b:= 5
else if o = '0110' then b:= 6
else if o = '0111' then b:= 7
else if o = '1000' then b:= 8
else if o = '1001' then b:= 9
else if o = '1010' then b:= 10
else if o = '1011' then b:= 11
else if o = '1100' then b:= 12
else if o = '1101' then b:= 13
else if o = '1110' then b:= 14
else if o = '1111' then b:= 15;
end;
begin
for a:= 16 downto 1 do
begin
z:= Concat(r[32],r[1],r[2],r[3],r[4],r[5],r[4],r[5],r[6],r[7],r[8],r[9],
r[8],r[9],r[10],r[11],r[12],r[13],r[12],r[13],r[14],r[15],r[16],r[17],
r[16],r[17],r[18],r[19],r[20],r[21],r[20],r[21],r[21],r[23],r[24],r[25],
r[24],r[25],r[26],r[27],r[28],r[29],r[28],r[29],r[30],r[31],r[32],r[1]);
_1:= k[a];
r:= z;
for j:= 1 to 48 do // xor
begin
v:= StrToInt(r[j]);
b:= StrToInt(_1[j]);
x:= v xor b;
_2:= Concat(_2, IntToStr(x));
end;
p:= Copy(_2, 1, 6); u:= p[1] + p[6]; o:= Copy(p, 2, 5); s(v, b);
rez:= rez + s1[v, b];
p:= Copy(_2, 7, 12); u:= p[1] + p[6]; o:= Copy(p, 2, 5); s(v, b);
rez:= rez + s2[v, b];
p:= Copy(_2, 13, 18); u:= p[1] + p[6]; o:= Copy(p, 2, 5); s(v, b);
rez:= rez + s3[v, b];
p:= Copy(_2, 19, 24); u:= p[1] + p[6]; o:= Copy(p, 2, 5); s(v, b);
rez:= rez + s4[v, b];
p:= Copy(_2, 25, 30); u:= p[1] + p[6]; o:= Copy(p, 2, 5); s(v, b);
rez:= rez + s5[v, b];
p:= Copy(_2, 31, 36); u:= p[1] + p[6]; o:= Copy(p, 2, 5); s(v, b);
rez:= rez + s6[v, b];
p:= Copy(_2, 37, 42); u:= p[1] + p[6]; o:= Copy(p, 2, 5); s(v, b);
rez:= rez + s7[v, b];
p:= Copy(_2, 43, 48); u:= p[1] + p[6]; o:= Copy(p, 2, 5); s(v, b);
rez:= rez + s8[v, b];
// ? ia?anoaiiaea
_2:= rez;
rez:= Concat(_2[16], _2[7], _2[20], _2[21], _2[29], _2[12], _2[28], _2[17],
_2[1], _2[15], _2[23], _2[26], _2[5], _2[18], _2[31], _2[10],
_2[2], _2[8], _2[24], _2[14], _2[32], _2[27], _2[3], _2[9],
_2[19], _2[13], _2[30], _2[6], _2[22], _2[11], _2[4], _2[25]);
for w:= 1 to 32 do
begin
v:= StrToInt(r[w]);
b:= StrToInt(l[w]);
x:= v xor b;
_2:= Concat(_2, IntToStr(x));
end;
l:= r;
r:= _2;
end;
_2:= Concat(l, r);
rez:= Concat(
_2[40], _2[8], _2[48], _2[16], _2[56], _2[24], _2[64], _2[32],
_2[39], _2[7], _2[47], _2[15], _2[55], _2[23], _2[63], _2[31],
_2[38], _2[6], _2[46], _2[14], _2[54], _2[22], _2[62], _2[30],
_2[37], _2[5], _2[45], _2[13], _2[53], _2[21], _2[61], _2[29],
_2[36], _2[4], _2[44], _2[12], _2[52], _2[20], _2[60], _2[28],
_2[35], _2[3], _2[43], _2[11], _2[51], _2[19], _2[59], _2[27],
_2[34], _2[2], _2[42], _2[10], _2[50], _2[18], _2[58], _2[26],
_2[33], _2[1], _2[41], _2[9], _2[49], _2[17], _2[57], _2[25]);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
output, put, key, c0, d0, k0: AnsiString;
e1: string[1];
e2: string[2];
begin
DecToBin(Form1.Memo1.Text, output);
BeginPerestanovka(output, put);
l:= Copy(put, 1, 32);
r:= Copy(put, 33, 64);
DecToBin(Form1.Memo3.Text, key);
PerestanovkaKeyB(key, key);
c0:= Copy(key, 1, 28);
d0:= Copy(key, 29, 56);
c[0]:= c0;
d[0]:= d0;
for w:= 1 to 2 do
begin
e1:= c[w-1];
c[w]:= Copy(c[w-1], 2, 28) + e1;
e1:= d[w-1];
d[w]:= Copy(d[w-1], 2, 28) + e1;
end;
for w:= 3 to 8 do
begin
e2:= c[w-1];
c[w]:= Copy(c[w-1], 3, 28) + e2;
e2:= d[w-1];
d[w]:= Copy(d[w-1], 3, 28) + e2;
end;
e1:= c[8];
c[9]:= Copy(c[8], 2, 28) + e1;
e1:= d[8];
d[w]:= Copy(d[8], 2, 28) + e1;
for w:= 10 to 15 do
begin
e2:= c[w-1];
c[w]:= Copy(c[w-1], 3, 28) + e2;
e2:= d[w-1];
d[w]:= Copy(d[w-1], 3, 28) + e2;
end;
e1:= c[15];
c[16]:= Copy(c[15], 2, 28) + e1;
e1:= d[15];
d[16]:= Copy(d[15], 2, 28) + e1;
pocledovatelnostiK;
FuncE;
Form1.Memo2.Text:= rez;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
output, put, key, c0, d0, k0: AnsiString;
e1: string[1];
e2: string[2];
begin
DecToBin(Form1.Memo2.Text, output);
BeginPerestanovka(output, put);
l:= Copy(put, 1, 32);
r:= Copy(put, 33, 64);
DecToBin(Form1.Memo3.Text, key);
PerestanovkaKeyB(key, key);
c0:= Copy(key, 1, 28);
d0:= Copy(key, 29, 56);
c[0]:= c0;
d[0]:= d0;
for w:= 1 to 2 do
begin
e1:= c[w-1];
c[w]:= Copy(c[w-1], 2, 28) + e1;
e1:= d[w-1];
d[w]:= Copy(d[w-1], 2, 28) + e1;
end;
for w:= 3 to 8 do
begin
e2:= c[w-1];
c[w]:= Copy(c[w-1], 3, 28) + e2;
e2:= d[w-1];
d[w]:= Copy(d[w-1], 3, 28) + e2;
end;
e1:= c[8];
c[9]:= Copy(c[8], 2, 28) + e1;
e1:= d[8];
d[w]:= Copy(d[8], 2, 28) + e1;
for w:= 10 to 15 do
begin
e2:= c[w-1];
c[w]:= Copy(c[w-1], 3, 28) + e2;
e2:= d[w-1];
d[w]:= Copy(d[w-1], 3, 28) + e2;
end;
e1:= c[15];
c[16]:= Copy(c[15], 2, 28) + e1;
e1:= d[15];
d[16]:= Copy(d[15], 2, 28) + e1;
pocledovatelnostiK;
FuncER;
Form1.Memo1.Text:= rez;
end;
end.
Страницы: 1 , 2