Цифровые компьютеры положили начало новому методу шифрова-
ния, основывающемуся на обработке бит, составляющих символы
исходного текста. Хотя побитовая обработка является вариацией
шифра замены, концепции, методы и возможности отличаются столь
значительно, что он должен рассматриваться, как отдельный вид
шифра.
Шифры побитовой обработки хорошо подходят для применения в
компьютерах, так как они используют операции, легко выполняемые
компьютерами.
В общем случае шифры побитовой обработки применимы только
для файлов компьютеров и не могут быть использованы для создания
печатной копии, так как побитовая обработка ведет к порождению
непечатных знаков. По этой причине предполагается, что любой
файл, зашифрованный методами побитовой обработки, будут оста-
ваться компьютерными файлами.
Шифры побитовой обработки преобразуют исходную информацию в
шифрограмму, изменяя исходную битовую комбинацию каждого символа
с помощью одного или нескольких следующих логических операторов:
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.