Чтение онлайн

на главную - закладки

Жанры

Шрифт:
...

Листинг 12.11. Функция получения части текста заданной длины, начиная с указанной позиции, в виде одной строки

function TfmTransposition.GetLine(Lines: TStrings;

nRow, nInd: Integer): String;

var

i, j, k: Integer;

s: String;

begin

Result := \'\

s := \'\

k := nInd;

for i := nRow to Lines.Count – 1 do

begin

for j := k to Length(Lines[i]) do

begin

s := s + Lines[i][j];

if Length(s) = Rear[0] then

begin

Result := s;

Exit;

end;

end;

k := 1;

end;

end;

Подготовительный этап мы рассмотрели, теперь остается рассмотреть основной код программы. Обработчики кнопок Onclick вызывают один и тот же метод и указывают необходимые параметры, чтобы зашифровать либо дешифровать текст сообщения. Процедура EncryptDecrypt в качестве параметров принимает источник текста сообщения, с которым нужно проделать необходимые действия, приемник преобразованного текста сообщения и тип преобразования. Последний параметр принимает одно из двух значений: 0 или 1. Значение О указывает на то, что будет производиться шифрование сообщения. Значение 1 указывает на то, что будет производиться дешифрование сообщения. Процедура EncryptDecrypt выполняет следующие действия. Сначала она пытается подготовить необходимую перестановку и, только если все прошло успешно, переходит к попытке преобразования текста сообщения, но предварительно делает еще одну проверку. Эта проверка заключается в следующем: нужно удостовериться в соответствии общей длины текста накладываемому на нее ограничению, то есть длина обязана быть кратна периоду транспозиции. Если все хорошо, то далее следует код преобразования текста сообщения с использованием подготовленной транспозиции. Для начала приведем исходный код, который находится в листинге 12.12.

...

Листинг 12.12. Шифрование/дешифрование текста сообщения

procedure TfmTransposition.btnEncryptMessageClick (Sender:

TObject);

begin

EncryptDecrypt(mmDecryptMessage.Lines,

mmEncryptMessage.Lines, 0);

end;

procedure TfmTransposition.btnDecpyptMessageClick(Sender:

TObject);

begin

EncryptDecrypt(mmEncryptMessage.Lines,

mmDecryptMessage.Lines, 1);

end;

procedure TfmTransposition.EncryptDecrypt(SrcLines,

DstLines: TStrings;

nKey: Integer);

var

i, j, Cnt: Integer;

s, EncryptMsg: String;

begin

if RecalcRearrangement(nKey) then

begin

//вычисляем общую длину текста

Cnt := 0;

for i := 0 to SrcLines.Count – 1 do

Inc(Cnt, Length(SrcLines[i]));

//проверяем кратность общей длины длине перестановки

if Cnt mod Rear[0] <> 0 then

begin

MessageDlg(\'Ошибка: текст сообщения не кратен длине

перестановки\', mtError, [mbOk], 0);

Exit;

end;

//преобразуем сообщение

Cnt := Rear[0];

DstLines.BeginUpdate;

DstLines.Clear;

for i := 0 to SrcLines.Count – 1 do

begin

EncryptMsg := \'\

for j := 1 to Length(SrcLines[i]) do

begin

if Cnt = Rear[0] then

begin

s := GetLine(SrcLines, i, j);

Cnt := 0;

end;

Inc(Cnt);

EncryptMsg := EncryptMsg + s[Rear[Cnt]];

end;

DstLines.Add(EncryptMsg);

end;

DstLines.EndUpdate;

end

else

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

[mbOk], 0);

end;

С подготовительным этапом мы разобрались, а теперь рассмотрим непосредственно сам процесс преобразования текста сообщения. Здесь переменная Cnt отвечает за то, какую часть очередной группы букв уже обработали. Если она равна количеству чисел в перестановке, то происходит переход к очередной группе букв сообщения. Алгоритм преобразования усложняется тем, что строки текста не обязательно кратны количеству чисел в перестановке. Поэтому для удобства мы написали функцию GetLine, получающую часть сообщения с указанной позиции в виде одной строки определенной длины, которая при необходимости склеена из нескольких подряд идущих строк. Теперь нам ничего не мешает заменить очередную букву сообщения соответствующей буквой из полученной строки. Результат работы приложения приведен на рис. 12.4.

Рис. 12.4. Результат работы приложения «Т ранспозиция с фиксированным периодом»

12.4. Шифр Виженера и его варианты

Ключ в шифре Виженера задается набором из п букв. Такие наборы подписываются с повторением под текстом сообщения, и полученные две последовательности складываются по модулю т, где т – количество букв в рассматриваемом алфавите (например, для русского алфавита каждая буква нумеруется от О (А) до 32 (Я) wn = 33). В результате получаем правило преобразования открытого текста И = xi + yi (mod т), где xi – буква в открытом тексте с номером i, yi – буква ключа, полученная сокращением числа i по модулю п. В табл. 12.1 приведен пример использования ключа ПБЕ.

Таблица 12.1

. Шифр Виженера с ключом ПБЕ

Шифр Виженера с периодом 1 называется шифром Цезаря. По сути, он представляет собой простую подстановку, в которой каждая буква некоторого сообщения М сдвигается циклически вперед на фиксированное количество мест по алфавиту. Именно это количество является ключом. Оно может принимать любое значение в диапазоне от 0 до т – 1. Повторное применение двух или более шифров Виженера будет называться составным шифром Виженера. Он имеет уравненией = xi + yi +… + zi (modm), где xi + yi +… + zi имеют различные периоды. Период их суммы, как и в составной транспозиции, будет наименьшим общим кратным отдельных периодов.

Если используется шифр Виженера с неограниченным неповторяющимся ключом, то мы имеем шифр Вернама, в котором й = xi + yi (mod т) и yi выбираются случайно и независимо среди чисел 0, 1…., т – 1. Если ключом служит текст, имеющий смысл, то имеем шифр «бегущего ключа».

Теперь перейдем к примеру. Рассмотрим одну из возможных реализаций шифра Цезаря. Как обычно, создадим новое приложение и, по аналогии с предыдущим примером, разместим на форме такие же компоненты. У вас получится приблизительно следующее приложение (рис. 12.5).

Рис. 12.5. Интерфейс приложения «Шифр Цезаря»

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

...

Листинг 12.13.

Объявление типов и класса нашей формы

type

//исходный алфавит русского языка

TRusSrcAlphabet = array [0..65] of Char;

//сопоставление букв алфавита открытого текста и зашифрованного

TRusDstAlphabet = array [Char] of Char;

TfmCryptography = class(TForm)

mmDecryptMessage: TMemo;

mmEncryptMessage: TMemo;

lbDecryptMessage: TLabel;

lbEncryptMessage: TLabel;

btnEncryptMessage: TButton;

btnDecpyptMessage: TButton;

edKey: TEdit;

lbKey: TLabel;

procedure btnEncryptMessageClick(Sender: TObject);

procedure btnDecpyptMessageClick(Sender: TObject);

private

{ Private declarations }

RusDstAlphabet: TRusDstAlphabet;

function GetKey: Integer;

procedure RecalcAlphabet(nKey: Integer);

function EncryptDecryptString(strMsg: String;

nKey: Integer): String;

public

{ Public declarations }

end;

var

RusSrcAlphabet: TRusSrcAlphabet =

\'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ\' +

\'абвгдеёжзийклмнопрстуфхцчшщъыьэюя\

fmCryptography: TfmCryptography;

Далее приведем описание работы методов, решающих определенные подзадачи, которые возникают в процессе решения основной проблемы. Итак, начнем рассмотрение с функции получения введенного пользователем ключа. Ее работа заключается в следующем. Сначала текстовое представление ключа преобразуется в численное представление. Далее проверяется, успешно ли прошло преобразование. Если все отлично, то возвращается полученное значение. В противном случае результатом функции будет -1, что свидетельствует о некорректном вводе пользователем ключа. Исходный код данной функции приведен в листинге 12.14.

Поделиться:
Популярные книги

Убивать чтобы жить 5

Бор Жорж
5. УЧЖ
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 5

Вперед в прошлое 3

Ратманов Денис
3. Вперёд в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 3

Последний Паладин. Том 13

Саваровский Роман
13. Путь Паладина
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 13

Локки 10. Потомок бога

Решетов Евгений Валерьевич
10. Локки
Фантастика:
фэнтези
юмористическое фэнтези
героическая фантастика
боевая фантастика
5.00
рейтинг книги
Локки 10. Потомок бога

Газлайтер. Том 6

Володин Григорий
6. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 6

Ключи мира

Кас Маркус
9. Артефактор
Фантастика:
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Ключи мира

Последний Паладин. Том 11

Саваровский Роман
11. Путь Паладина
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Последний Паладин. Том 11

Тринадцатый X

NikL
10. Видящий смерть
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Тринадцатый X

Ярар. Начало

Грехов Тимофей
1. Ярар
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ярар. Начало

Звездная Кровь. Экзарх II

Рокотов Алексей
2. Экзарх
Старинная литература:
прочая старинная литература
5.00
рейтинг книги
Звездная Кровь. Экзарх II

Камень. Книга 3

Минин Станислав
3. Камень
Фантастика:
фэнтези
боевая фантастика
8.58
рейтинг книги
Камень. Книга 3

Горизонт Вечности

Вайс Александр
11. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Горизонт Вечности

Долг

Кораблев Родион
7. Другая сторона
Фантастика:
боевая фантастика
5.56
рейтинг книги
Долг

Черный Маг Императора 13

Герда Александр
13. Черный маг императора
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Черный Маг Императора 13