соответствие буквам перестановки буквы открытого текста. Для этого массив сопоставления символов изначально заполняется таким образом, чтобы каждый символ соответствовал самому себе. Это происходит в следующих строках метода:

...

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;

Теперь, используя все описанные функции, мы без труда можем зашифровать либо дешифровать сообщение. Например, чтобы зашифровать его, мы подготавливаем массив соответствия букв вызовом функции RecalcAlphabet с параметром 0. После чего для каждой строки открытого текста вызываем функцию EncryptDecryptString и в качестве результата получаем зашифрованную строку. Обработчики событий OnClick соответствующих кнопок шифруют либо дешифруют весь текст. Основная идея каждого из методов заключается в том, чтобы проверить корректность заданной перестановки, после чего производится предварительная подготовка алфавита сопоставления, и далее сообщение преобразуется (листинг 12.8).

...

Листинг 12.8.

Шифрование/дешифрование сообщения

procedure TfmSubstitution.btnEncryptMessageClick(Sender:

TObject);

var

i: Integer;

begin

//проверяем корректность ввода перестановки

if ValidateRearrangement then

begin

//создаем алфавит преобразования открытого текста

RecalcAlphabet(0);

//предотвращаем перерисовку компонента до тех пор,

//пока не зашифруем все строки сообщения

mmEncryptMessage.Lines.BeginUpdate;

//очищаем текстовый редактор

mmEncryptMessage.Clear;

//шифруем открытый текст построчно

for i := 0 to mmDecryptMessage.Lines.Count – 1 do

mmEncryptMessage.Lines.Add(EncryptDecryptString

(mmDecryptMessage.Lines[i]));

//разрешаем перерисовку компонента

mmEncryptMessage.Lines.EndUpdate;

end

else

MessageDlg ('Ошибка: символы подстановки заданы неверно',

mtError, [mbOk], 0);

end;

procedure TfmSubstitution.btnDecpyptMessageClick (Sender:

TObject);

var

i: Integer;

begin

//проверяем корректность ввода перестановки

if ValidateRearrangement then

begin

//создаем алфавит преобразования шифрованного текста

RecalcAlphabet (1);

mmDecryptMessage.Lines.BeginUpdate;

mmDecryptMessage.Clear;

//дешифруем шифрованный текст построчно

for i := 0 to mmEncryptMessage.Lines.Count – 1 do

mmDecryptMessage.Lines.Add(EncryptDecryptString

(mmEncryptMessage.Lines [i]));

mmDecryptMessage.Lines.EndUpdate;

end

else

MessageDlg('Ошибка: символы подстановки заданы неверно',

mtError, [mbOk], 0);

end;

В итоге мы получили вполне рабочий вариант приложения, способного без особого труда шифровать и дешифровать сообщения. На рис. 12.2 представлен результат работы данного приложения.

Рис. 12.2. Результат работы приложения «Шифр простой подстановки»

12.3. Транспозиция

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

Таким образом, для d = 5 в качестве перестановки можно взять 23154. Это будет означать, что т1т2 тЗт4т5т6т7т8т9 тЮ… переходит в т2 тЗт1т5т4т7т8т6т10т9… Последовательное применение двух или более транспозиций будет называться составной транспозицией. Если периоды этих транспозиций d1…., ds, то, очевидно, в результате получится транспозиция периода d, где d – наименьшее общее кратное d1…., ds.

Теперь, зная определение данного шифра, можно перейти к примеру одной из возможных его реализаций. Для этого, как и в предыдущем случае, создадим новое приложение, а на форму поместим те же самые компоненты, за исключением редактора значений и кнопки для генерации перестановки. Вместо них используем следующие компоненты: текстовое поле класса TEdit и еще один компонент класса TLabel с соответствующими HMeHaMHedRearrangement и IbRearrangement. Когда вы закончите, то в результате должно получиться нечто подобное изображенному на рис. 12.3.

Рис. 12.3. Интерфейс программы «Транспозиция с фиксированным периодом»

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

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

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

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

Отметить Добавить цитату