Энциклопедия Turbo Pascal. Главы 5-8
Страница 18. Шифры перестановки


Шифры перестановки

     Одним из ранних вариантов шифра перестановки был  разработан
стандартами в 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.

     Хотя коды перестановки могут быть  эффективными,  алгоритмы,
если  требуется  высокий  уровень  секретности,  становятся очень
сложными.

 
« Предыдущая статья   Следующая статья »