Следующим объектом нашего рассмотрения является функция предварительной подготовки алфавита преобразования для шифрования либо дешифрования сообщения. У метода RecalcAlphabet есть параметр пКеу, который в зависимости от своего значения показывает, что является ключом. Возможными значениями пКеу являются 0 и 1. Значение 0 указывает на то, что будет производиться шифрование сообщения и требуется поставить в соответствие буквам открытого текста буквы перестановки. Значение 1, напротив, указывает на то, что будет производиться дешифрование сообщения и требуется поставить в соответствие буквам перестановки буквы открытого текста. Для этого массив сопоставления символов изначально заполняется таким образом, чтобы каждый символ соответствовал самому себе. Это происходит в следующих строках метода:
for Ch := Low(RusDstAlphabet) to High(RusDstAlphabet) do RusDstAlphabet[Ch] := Ch;
После чего требуется подкорректировать данный массив таким образом, чтобы выполнялось требуемое соответствие. Для этого мы проходим по всем элементам редактора значений vleSubstn поправляем массив, указывая в качестве индекса элемента то, чему ставится соответствие, а в качестве значения элемента массива – то, что является соответствием.
for i := 1 to vleSubst.RowCount – 1 do
RusDstAlphabet[vleSubst.Cells[nKey, i][1]] :=
vleSubst.Cells[1 – nKey, i][1];
Редактор значений vleSubst предназначен для сопоставления букв верхнего регистра. Нам же требуется избавиться от различия между буквами верхнего и нижнего регистров. Для этого мы дополнительно производим следующие действия:
for i := 1 to vleSubst.RowCount – 1 do
RusDstAlphabet[LowCaseRus(vleSubst.Cells[nKey, i][1])] :=
LowCaseRus(vleSubst.Cells[1 – nKey, i][1]);
Мы рассмотрели работу данного метода по частям. Его полный код приведен в листинге 12.6. Как видите, все относительно просто. Здесь мы используем вспомогательную функцию LowCaseRus.
Листинг 12.6.
Функция предварительной подготовки алфавита преобразования
procedure TfmSubstitution.RecalcAlphabet(nKey: Integer);
var
Ch: Char;
i: Integer;
begin
//предварительно все символы в алфавите шифрования
//соответствуют символам из незашифрованного алфавита
for Ch := Low(RusDstAlphabet) to High(RusDstAlphabet) do
RusDstAlphabet[Ch] := Ch;
//формируем алфавит отдельно для каждого из регистров букв
//здесь для верхнего
for i := 1 to vleSubst.RowCount – 1 do
RusDstAlphabet[vleSubst.Cells[nKey, i][1]] :=
vleSubst.Cells[1 – nKey, i][1];
//здесь для нижнего
for i := 1 to vleSubst.RowCount – 1 do
RusDstAlphabet[LowCaseRus(vleSubst.Cells[nKey, i][1])] :=
LowCaseRus(vleSubst.Cells[1 – nKey, i][1]);
end;
Еще одной вспомогательной функцией является функция преобразования строки символов с помощью алфавита преобразования в соответствии с указанной операцией. Работа ее довольно проста. В цикле осуществляется прямой проход по строке, и каждый символ, принадлежащий ей, заменяется соответствующим символом алфавита преобразования. В итоге мы получаем зашифрованную либо дешифрованную строку. Посмотреть исходный код данного метода можно в листинге 12.7.
Листинг 12.7.
Преобразование строки при помощи массива сопоставления
function TfmSubstitution.EncryptDecryptString(strMsg: String):
String;
var
i: Integer;
begin
//преобразуем строку посимвольно
for i := 1 to Length(strMsg) do
strMsg[i] := RusDstAlphabet[strMsg[i]];
Result := strMsg;
end;