Рис. 12.3. Интерфейс программы «Транспозиция с фиксированным периодом»
Текстовое поле edRearrangement предназначено для задания перестановки, которая будет использоваться при шифровании. Перестановка будет задаваться числами, разделенными пробелом, а их количество задаст период транспозиции. По остальному интерфейсу наше приложение аналогично предыдущему.
Стоит отметить одну неприятную особенность данного шифра. Поскольку период фиксирован, то на текст накладывается определенное ограничение. Оно заключается в том, что длина текста должна быть кратна периоду. Существует несколько вариантов решения данной проблемы. Можно дополнять открытый текст какими-либо символами. И тогда зашифровать сообщение не составит труда. Если эти символы заранее определены, то это облегчит задачу противника по вскрытию шифра. Другой вариант – переписать сообщение, используя, например, синонимы, либо удалив часть сообщения, которую легко восстановить из контекста, таким образом, чтобы длина текста стала кратной периоду.
Теперь перейдем к рассмотрению исходного кода нашего приложения. Как и в прошлый раз, начнем с объявления класса необходимых нам типов, а также класса формы. Соответствующий программный код показан в листинге 12.9. Здесь мы ввели целочисленную константу, ограничивающую длину задаваемого периода. В данном случае она равна 100. Нам понадобится помнить саму перестановку, при помощи которой будет осуществляться транспозиция сообщения, поэтому вводится соответствующий тип.Листинг 12.9.
Объявление типов и класса нашей формы
const
MaxTerm = 100;
type
TRearrangement = array [0..MaxTerm] of Integer;
TfmTransposition = class(TForm)
mmDecryptMessage: TMemo;
mmEncryptMessage: TMemo;
lbDecryptMessage: TLabel;
lbEncryptMessage: TLabel;
lbRearrangement: TLabel;
edRearrangement: TEdit;
btnEncryptMessage: TButton;
btnDecpyptMessage: TButton;
procedure btnEncryptMessageClick(Sender: TObject);
procedure btnDecpyptMessageClick(Sender: TObject);
private
{ Private declarations }
Rear: TRearrangement;
function RecalcRearrangement(nKey: Integer): Boolean;
function GetLine(Lines: TStrings;
nRow, nInd: Integer): String;
procedure EncryptDecrypt(SrcLines, DstLines: TStrings;
nKey: Integer);
public
{ Public declarations }
end;
Теперь перейдем к рассмотрению исходного кода решаемых в данном случае подзадач. Первой функцией, с которой мы начнем, будет функция разбора введенной строки, выделяющая перестановку из нее и проверяющая, является ли она допустимой.
Функция RecalcRearrangement подготавливает перестановку требуемым образом для шифрования либо дешифрования в зависимости от параметра пКеу, который принимает два значения: 0 и 1. Значение 0 указывает на то, что будет производиться шифрование сообщения и дополнительных действий по подготовке перестановки не требуется, за исключением проверки ее корректности. Значение 1, напротив, указывает на то, что будет производиться дешифрование сообщения и требуется еще дополнительно преобразовать перестановку так, чтобы она была симметрична исходной, в этом случае процесс дешифрования ничем не будет отличаться от процесса шифрования.
Чтобы введенная перестановка считалась корректной, необходимо и достаточно выполнить три следующих требования:
• введены только числа через пробел;
• все числа не повторяются;
• числа находятся в диапазоне от 1 до их общего количества.