Страница 18 из 37
Шифры перестановки Одним из ранних вариантов шифра перестановки был разработан стандартами в 475 году до нашей эры. Он использовал устройство в виде длинной узкой ленты, которая накручивалась на цилиндр и на которой сообщение писалось поперек. Лента затем разматывалась и поставлялась получателю, который имел точно такой же цилиндр. Те- оретически возможно прочитать ленту без цилиндра, так как буквы все-таки сохраняют порядок следования. Однако, на практике данный метод остается только возможным, так как необходимо перепробовать большое количество различных размеров цилиндров прежде, чем сооб- щение начинает вырисовываться.
Вы можете создать машинную версию такого шифра, поместив исходное текстовое сообщение в матрицу одним способом и выведя его другим способом. Для того, чтобы сделать это, для хранения кодируемого сообщения используется одновременная строка, но сооб- щение записывается в дисковый файл в виде матрицы. В нашем вари- анте исходный текст, представляющий собой строку длиной 100 байт, записывается на диск, как матрица 5х20. Однако, вы могли бы использовать матрицу любой другой размерности. Так как сообщение помещается в матрицу фиксированного размера, то существует веро- ятность того, что не все элементы матрицы будут использованы. Это делает необходимым инициализацию матрицы перед помещением в нее исходного текста. На практике лучше инициализировать матрицу про- извольными символами, однако, для простоты используется символ "#".
Если вы поместите сообщение
meet me at sunset
в матрицу, она будет выглядеть следующим образом
¦ m ¦ e ¦ e ¦ t ¦ ¦ +---+---+---+---+---+ ¦ m ¦ e ¦ ¦ a ¦ t ¦ +---+---+---+---+---+ ¦ ¦ s ¦ u ¦ n ¦ s ¦ +---+---+---+---+---+ ¦ e ¦ t ¦ # ¦ # ¦ # ¦ +---+---+---+---+---+ ¦ # ¦ # ¦ # ¦ # ¦ # ¦
Если вы затем осуществите запись матрицы по столбцам, то сообщение будет выглядеть следующим образом:
mm e...eest...e u...tan... ts
где точки обозначают соответствующее количество символов "#". Для декодирования сообщения заполняются столбцы матрицы. Затем матри- ца может быть отображена в нормальном порядке. Программа Skytale использует данный метод для кодирования и декодирования сообще- ний:
{шифр skytale} { примечание: наибольшее сообщение, которое может быть за- кодировано, состоит из 100 байт } program skytale; type str100 = string[100]; str80 = string[80];
var inf, outf:str80; sky: str100; t: integer; ch: char;
procedure code(inf, outf: str80); var infile, outfile: file of char; ch: char; t, t2: integer;
begin assign(infile, inf); reset(infile); assign(outfile, outf); rewrite(outfile);
t := 1; { считывание текстового файла, как одномерной матрицы } while (not eof(infile)) and (t<=100) do begin Read(infile, sky[t]); t := t+1; end;
{ запись в матрицу размера 5х20 } for t := 1 to 5 do for t2 := 0 to 19 do Write(outfile, sky[t+(t2*5)]);
WriteLn('файл закодирован');
close(infile); close(outfile); end; {code}
procedure decode(inf, outf: str80); var infile, outfile: file of char; ch: char; t, t2: integer;
begin assign(infile, inf); reset(infile); assign(outfile, outf); rewrite(outfile);
{ считывание матрицы размером 5х20 } for t := 1 to 5 do for t2 := 0 to 19 do Read(infile, sky[t+(t2*5)]);
{ вывод в качестве строки } for t := 1 to 100 do Write(outfile, sky[t]);
WriteLn('файл декодирован'); close(infile); close(outfile); end; {decode}
begin { заполнение символов "#" } for t := 1 to 100 do sky[t] := '#'; Write('введите имя входного файла: '); ReadLn(inf); Write('введите имя выходного файла: '); ReadLn(outf); Write('кодировать или декодировать (C or D): '); ReadLn(ch); if upcase(ch)='C' then code(inf, outf) else if upcase(ch)='D' then decode(inf, outf); end.
Существуют другие методы получения перемешанных сообщений. Один метод, особенно подходящий для компьютера, использует пе- рестановку букв внутри сообщения с некоторым алгоритмом. Следую- щая программа перемешивает буквы:
{шифр перемешивания. Длина сообщения не должна превышать 100 символов }
program transpose; type str100 = string[100]; str80 = string[80];
var inf, outf: str80; message: str100; ch: char; t: integer;
procedure code(inf, outf: str80); var infile, outfile: file of char; temp: char; t, t2: integer;
begin assign(infile, inf); reset(infile); assign(outfile, outf); rewrite(outfile);
t := 1; while (not eof(infile)) and (t<=100) do begin Read(infile, message[t]); t := t+1; end; message[t-1] := {удаление знака конца файла }
{ теперь перемешиваются символы } for t2 := 0 to 4 do for t := 1 to 4 do begin temp := message[t+t2*20]; message[t+t2*20] := message[t+10+t2*20]; message[t+10+t2*20] := temp; end;
{now write it out} for t := 1 to 100 do Write(outfile, message[t]);
WriteLn('файл закодирован'); close(infile); close(outfile); end; {code}
procedure decode(inf, outf: str80); var infile, outfile: file of char; temp: char; t, t2: integer;
begin assign(infile, inf); reset(infile); assign(outfile, outf); rewrite(outfile);
t := 1; while (not eof(infile)) and (t<=100) do begin Read(infile, message[t]); t := t+1; end; message[t-1] := '#'; {удаление знака конца файла }
{теперь перемешиваются символы } for t2 := 0 to 4 do for t := 1 to 4 do begin temp := message[t+t2*20]; message[t+t2*20] := message[t+10+t2*20]; message[t+10+t2*20] := temp; end;
{ теперь осуществляем вывод } for t := 1 to 100 do Write(outfile, message[t]);
WriteLn('файл декодирован'); close(infile); close(outfile); end; {decoded}
begin for t := 1 to 100 do message[t] := '#'; Write('введите имя входного файла : '); ReadLn(inf); Write('введите имя выходного файла : '); ReadLn(outf); Write('кодировать или декодировать (C or D): '); ReadLn(ch); if upcase(ch)='C' then code(inf, outf) else if upcase(ch)='D' then decode(inf, outf); end.
Хотя коды перестановки могут быть эффективными, алгоритмы, если требуется высокий уровень секретности, становятся очень сложными.
|