Задание. Изучение симметричного алгоритма шифрования (на примере программы cript.pas).
Программа содержит 2 процедуры – шифрование текста и дешифровка текста, зашифрованного с помощью симметричного алгоритма.
Разберем текст программы. В программе объявлены глобальные переменные
- text_in – строка, предназначенная для шифрования;
- text_out – строка зашифрованного текста,
- cript_st – ключевая строка.
Объявлена переменная alf_st, строка, в которой перечислены все допустимые символы, которые могут содержаться в шифруемой строке и ключевом слове.
До начала работы процедур шифрования или дешифровки нам надо выполнить подготовительную работу. Имея доступ к строке допустимых символов, мы можем любому числу i от 1 до длины строки alf_st поставить в соответствие допустимый символ alf_st[i]. Надо организовать возможность получения обратной зависимости. Для этого заведем массив alf2num с элементами типа integer, в котором индексами являются символы с кодами от 1 до 255. Заполним этот массив.
Var
text_in, text_out, cript_st, alf_st: string;
|
|
alf2num: array [chr(1).. chr(255)] of integer;
i,ln: integer;
Begin
alf_st:='ячсмитьбюфывапролджэйцукенгшщзхъЯЧСМИТЬБЮФЫВАПРОЛДЖЭЙЦУКЕНГШЩЗХЪ 1234567890.,+=)(-!?';
ln:=length(alf_st);
for i:=1 to ln do begin
alf2num[alf_st[i]]:=i;
end;
Теперь, когда подготовительная работа окончена, рассмотрим процедуру шифрования текста. В процедуру передается шифруемая строка text_in и ключевая строка cript_st.
Procedure cript_in (criptin, key_text: string);
Var
cript_text, textout: string;
d, i, text_len: integer;
Begin
text_len:=length(criptin); {Определяем длину строки для шифрования}
cript_text:=key_text;
{Формируем ключевую строку путем повторения ключевого слова, пока ее длина не превысит длину шифруемой строки}
while length(cript_text)<=text_len do begin
cript_text:= cript_text+key_text;
end;
textout:='';
{Вычисляем по очереди каждый зашифрованный символ. Для этого определяем номера очередных символов шифруемой и ключевой строк в строке допустимых символов, складываем их и ищем остаток от деления полученного числа на длину алфавита. Таким образом, мы получаем число, лежащее в диапазоне от 1 до длины алфавита. Находим символ, соответствующий этому числу, и записываем его в результирующую (зашифрованную) строку.}
for i:=1 to text_len do begin
if alf2num[criptin[i]]=-1 then begin
writeln('Недопустимый символ', criptin[i]);
exit;
end;
d:=alf2num[criptin[i]]+alf2num[cript_text[i]];
d:= d mod ln;
textout:= textout+alf_st[d];
end;
writeln(textout); {процедура выводит на экран зашифрованный текст}
end;
Процедура дешифровки очень похожа на процедуру шифрования, с той лишь разницей, что вместо складывания номеров символов исходной и ключевой строк, мы ищем их разность и, затем, если получается отрицательный ответ, прибавляем к нему длину алфавита, с тем, чтобы результирующее число находилось в диапазоне между 1 и длиной алфавита.
|
|
Procedure cript_out (criptout, key_text: string);
Var
cript_text, textin: string;
d, i, text_len: integer;
Begin
text_len:=length(criptout); {Определяем длину строки для шифрования}
cript_text:=key_text;
{Формируем ключевую строку путем повторения ключевого слова, пока ее длина не превысит длину шифруемой строки}
while length(cript_text)<=text_len do begin
cript_text:= cript_text+key_text;
end;
textin:='';
for i:=1 to text_len do begin
if alf2num[criptout[i]]=-1 then begin
writeln('Недопустимый символ', criptout[i]);
exit;
end;
d:=alf2num[criptout[i]]-alf2num[cript_text[i]];
d:= d mod ln;
textin:= textin+alf_st[d];
end;
writeln(textin); {процедура выводит на экран расшифрованный текст}
end;