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


Шифры побитовой обработки

     Цифровые компьютеры положили начало новому  методу  шифрова-
ния,  основывающемуся  на  обработке  бит,  составляющих  символы
исходного текста.  Хотя побитовая  обработка  является  вариацией
шифра  замены,  концепции,  методы и возможности отличаются столь
значительно,  что он должен рассматриваться,  как  отдельный  вид
шифра.

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

     В общем  случае  шифры  побитовой обработки применимы только
для файлов компьютеров и не могут быть использованы для  создания
печатной  копии,  так  как побитовая обработка ведет к порождению
непечатных знаков.  По этой  причине  предполагается,  что  любой
файл,  зашифрованный  методами  побитовой обработки,  будут оста-
ваться компьютерными файлами.

     Шифры побитовой обработки преобразуют исходную информацию  в
шифрограмму,  изменяя исходную битовую комбинацию каждого символа
с помощью одного или нескольких следующих логических операторов:

            AND       OR        NOT        XOR

     Турбо Паскаль является одним из лучших языков для реализации
шифров побитовой обработки, так как он поддерживает данные опера-
торы для использования над типом данных bite. Когда данный опера-
тор применяется к байтовым переменным, операция осуществляется на
байт-байтовой основе,  легко выполняя изменения состояний битов в
байте.

     Простейший и  наименее стойкий шифр использует только опера-
тор NOT (напомним, что оператор NOT вызывает инверсию каждого би-
та в байте:  1 переходит в 0,  а 0 в 1). Следовательно, байт, ин-
вертированный дважды, равен исходному. Следующая программа, назы-
ваемая Complement (дополнение),  шифрует любой текстовый файл ин-
вертированием битов внутри каждого символа. Так как Турбо Паскаль
строг в отношении типов переменных, в программе следует использо-
вать переменные типа byte (байтовые),  а  не  char  (символьные),
чтобы можно было применить операторы побитовой обработки.

     { шифр дополнения до 1 }
     program complement;
     type
       str80 = string[80];
     var
       inf,out: str80;
       ch: char;
       t: integer;

     procedure code(inf, outf: str80);
     var
       infile, outfile: file of byte;
       ch: byte;

     begin
       assing(infile, inf);
       reset(infile);
       assign(outfile, outf);
       rewrite(outfile);

       while not eof(infile) do
       begin
         Read(infile, ch);
         ch := not ch;
         Write(outfile, ch);
       end;

       WriteLn('файл закодирован');
       close(infile); close(outfile);
     end; {code}

     procedure decode(inf, outf: str80);
     var
       infile, outfile: file of byte;
       ch: byte;

     begin
       assign(infile, inf);
       reset(infile);
       assign(outfile, outf);
       rewrite(outfile);

       while not eof(infile) do
       begin
         Read(infile, ch);
         ch := not ch;
         Write(outfile, ch);
       end;

       WriteLn('файл декодирован');
       close(infile); close(outfile);
     end; {decoded}

     begin
       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.

     Трудно показать,  как будет выглядеть шифрованное сообщение,
так  как побитовая обработка,  применяемая здесь,  в общем случае
порождает непечатные символы. Попробуйте шифр на вашем компьютере
и  проанализируйте  полученный  файл;  он  будет выглядеть вполне
засекреченным.

     Существует два недостатка в данной простой схеме шифрования.
Во-первых,  программа шифрования не требует ключа для декодирова-
ния,  следовательно, любой имеющий доступ к программе может деко-
дировать файл.  Во-вторых, и возможно это более важно, данный ме-
тод мог бы разгадать любой опытный программист.

     В улучшенном методе кодирования с помощью побитовой обработ-
ки используется оператор XOR. Оператор XOR имеет следующую табли-
цу истинности:

         XOR ¦  0 ¦  1
         ----+----+----
          0  ¦  0 ¦  1
         ----+----+----
          1  ¦  1 ¦  0

     Результат операции XOR равен TRUE (истина)  тогда  и  только
тогда,  когда один оператор равен TRUE,  а второй - false (ложь).
Это дает XOR уникальные свойства: если выполнить операцию XOR над
двумя байтами,  один из которых называется ключем,  а затем взять
результат и ключ и снова применить к ним операцию XOR,  то в  ре-
зультате получим исходный байт, как показано ниже:

             1101   1001
     XOR     0101   0011  /ключ/
             -----------
             1000   1010
                                             равны
             1000   1010
     XOR     0101   1001  /ключ/
             -----------

             1101   1001

     Будучи примененными  для кодирования файлов,  данный процесс
разрешает две проблемы,  присущие методу, основанному на операции
инвертирования.  Во-первых,  так  как  применяется ключ,  наличие
только программы декодирования  не  позволяет  дешифровать  файл;
во-вторых, из-за того, что использование ключа делает каждый файл
своеобразным,  то он будет очевиден тем,  кто изучал  только  вы-
числительную технику.

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

     { шифр на основе операции XOR с ключем }
     program xor_wiht_key;
     type
       str80 = string[80];

     var
       inf, outf: str80;
       key: byte;
       ch: char;
       t: integer;

     procedure code(inf, outf: str80; key: byte);
     var
       infile, outfile: file of byte;
       ch: byte;

     begin
       assign(infile, inf);
       reset(infile);
       assign(outfile, outf);
       rewrite(outfile);

       while not eof(infile) do
       begin
         Read(infile, ch);
         ch := key xor ch;
         Write(outfile, ch);
       end;

       WriteLn('файл закодирован');
       close(infile); close(outfile);
     end; {code}

     procedure decode(inf, outf: str80; key: byte);
     var
       infile, outfile: file of byte;
       ch: byte;

     begin
       assign(infile, inf);
       reset(infile);
       assign(outfile, outf);
       rewrite(outfile);

       while not eof(infile) do
       begin
       Read(infile, ch);
          ch := key xor ch;
          Write(outfile, ch);
       end;

       WriteLn('файл декодирован');
       close(infile); close(outfile);
     end; {decode}

     begin
       Write('введите имя входного файла: ');
       ReadLn(inf);
       Write('введите имя выходного файла; ');
       ReadLn(outf);
       Write(' введите односимвольный ключ : ');
       ReadLn(ch);
       key := ord(ch);
       Write('кодировать или декодировать (C or D): ');
       ReadLn(ch);
       if upcase(ch)='C' then code(inf, outf, key)
       else if upcase(ch)='D' then decode(inf, outf, key);
     end.

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