КИРИЛЛ ТКАЧЕНКО, инженер 1-й кат., ФГАОУ ВО «Севастопольский государственный университет», tkachenkokirillstanislavovich@gmail.com
Энигмоподобная система на школьном алгоритмическом языке
Описывается программная реализация энигмоподобной системы на школьном алгоритмическом языке. Эта система отличается от «классических» машин типа «Энигма» используемым алфавитом и ротором. Программа будет полезна изучающим информатику и программирование
Для изучения информатики, программирования и сходных дисциплин нужны в первую очередь интересные примеры, которые имеют отношение к практике, достаточно интересны, но при этом имеют умеренную сложность решения и проработки. Таким примером может являться программная реализация энигмоподобной системы.
Шифровальные машины типа «Энигма» достаточно известны [1]. При этом их программная реализация имеет относительно небольшую сложность [1, 2]. Чтобы обеспечить воспроизводимость для различных систем и языков программирования, в качестве генератора псевдослучайных чисел (ГПСЧ) можно использовать линейный конгруэнтный метод [3]. Стоит отметить, что на языке 1С имеется программная реализация [4].
Не повторяясь [1, 2, 4], вкратце можно описать энигмоподобную систему следующим образом.
Шифрование осуществляется символ за символом. Для шифрования и дешифрования используется конечное число колес. Входной алфавит и алфавит, нанесенный на колеса, совпадают. На колеса символы алфавита нанесены в случайном порядке, который задан ключом шифрования и алгоритмом формирования ГПСЧ.
Шифрование символа производится по всем колесам: следующий номер символа содержится в «ячейке» текущего колеса по номеру текущего символа. После шифрования символа все колеса поворачиваются так, чтобы символ с наименьшим номером – первый – стал последним.
Дешифрование производится в обратном порядке колес, при этом начальное положение колес должно совпадать с таким для шифрования, и по номеру символа, содержащемуся в «ячейке» колеса, определяется номер предыдущего символа.
Вначале программы определяются константы и переменные. В константах Алфавит находится используемый для шифрования и дешифрования алфавит, в МаксНомерКолеса – наибольший номер колеса при нумерации с нуля, МаксНомерСимвола – наибольший номер символа при нумерации с нуля. Переменная СемяГПСЧ, хранящая текущее значение ГПСЧ, инициализируется нулем:
лит Алфавит = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
цел МаксНомерКолеса = 6;
цел МаксНомерСимвола = 32;
цел СемяГПСЧ = 0;
Главный алгоритм Энигма начинается с определения переменных.
В двумерном массиве Ротор помещаются шифровальные колеса, его строки соответствуют отдельным колесам, а столбцы – отдельным символам.
В целочисленной переменной МойКлюч располагается текущее значение ключа.
В строках СтрокаИсходная, СтрокаЗашифрованная, СтрокаРасшифрованная находятся значения соответственно для исходной, зашифрованной и расшифрованной строк.
Целочисленные переменные i, j, k, l хранят значения счетчиков циклов и индексов элементов массивов:
алг Энигма
нач
цел таб Ротор[0 : МаксНомерКолеса, 0 : МаксНомерСимвола];
цел МойКлюч;
лит СтрокаИсходная;
лит СтрокаЗашифрованная;
лит СтрокаРасшифрованная;
цел i, j, k, l;
Вначале происходит инициализация значения ключа МойКлюч и строки для шифрования СтрокаИсходная. Переменным СтрокаЗашифрованная и СтрокаРасшифрованная присваивается значение пустой строки:
МойКлюч := 1;
СтрокаИсходная := "ААААААААМАМАМЫЛАРАМУАААААААА";
СтрокаЗашифрованная := "";
СтрокаРасшифрованная := "";
Для шифрования вызовом подпрограммы НовыйРотор создается новый ротор для значения ключа МойКлюч. Для каждого исходного символа с позицией i в исходной строке определяется его порядковый номер в используемом алфавите k:
НовыйРотор(МойКлюч, Ротор);
нц для i от 1 до длин(СтрокаИсходная)
k := АлфавитНомер(СтрокаИсходная[i]);
Затем по всем колесам в роторе от 0 до МаксНомерКолеса происходит прогонка номера символа через каждое колесо в прямом порядке, а именно номер символа в следующем колесе определяется из ячейки рассматриваемого колеса потекущему номеру:
нц для j от 0 до МаксНомерКолеса
k := Ротор[j, k];
кц
Зашифрованный символ конкатенируется с результатом, происходит поворот ротора и переход к следующему символу в строке:
СтрокаЗашифрованная := СтрокаЗашифрованная + Алфавит[k + 1];
Поворот(Ротор);
кц
Для дешифрования вызовом подпрограммы НовыйРотор создается новый ротор для значения ключа МойКлюч.
Для каждого зашифрованного символа с позицией i в зашифрованной строке определяется его порядковый номер в используемом алфавите k:
НовыйРотор(МойКлюч, Ротор);
нц для i от 1 до длин(СтрокаЗашифрованная)
k := АлфавитНомер(СтрокаЗашифрованная[i]);
Затем по всем колесам в роторе от МаксНомерКолеса до 0 происходит прогонка номера символа через каждое колесо в обратном порядке.
Для этого номер символа ищется в массиве отдельного колеса и предыдущим номером символа считается его индекс в массиве:
нц для j от МаксНомерКолеса до 0 шаг -1
нц для l от 0 до МаксНомерСимвола
если Ротор[j, l] = k
то
k := l;
выход
все
кц
кц
Расшифрованный символ конкатенируется с результатом, происходит поворот ротора и переход к следующему символу в строке:
СтрокаРасшифрованная := СтрокаРасшифрованная + Алфавит[k + 1];
Поворот(Ротор);
кц
На стандартное устройство вывода отображаются строки исходная, зашифрованная и расшифрованная, алгоритм завершается:
вывод СтрокаИсходная, нс;
вывод СтрокаЗашифрованная, нс;
вывод СтрокаРасшифрованная, нс;
кон
Подпрограмма НовыйРотор служит для создания и пересоздания нового ротора. В целочисленный аргумент МойКлюч, на основе которого колеса ротора заполняются, эта величина помещается в семя генератора псевдослучайных чисел СемяГПСЧ. Ротор помещается в результат Ротор. Целочисленные переменные i, j, t1, t2 хранят в себе значения счетчиков циклов и индексы.
алг НовыйРотор(цел МойКлюч, рез цел таб Ротор[0 : МаксНомерКолеса, 0 : МаксНомерСимвола])
нач
цел i, j;
цел t1, t2;
СемяГПСЧ := МойКлюч;
Для всех колес ротора каждому символу присваивается его номер по умолчанию, который соответствует порядковому номеру:
нц для i от 0 до МаксНомерКолеса
нц для j от 0 до МаксНомерСимвола
Ротор[i, j] := j;
кц
После этого происходит взбивание колес ротора. Для каждого символа колеса происходит его попарный обмен со случайным соседом:
нц для j от 0 до МаксНомерСимвола
t1 := int(ГПСЧ * МаксНомерСимвола);
t2 := Ротор[i, j];
Ротор[i, j] := Ротор[i, t1];
Ротор[i, t1] := t2;
кц
кц
кон
Следующая подпрограмма Поворот осуществляет поворот колес ротора.
Аргумент-результат Ротор содержит колеса ротора для поворота. Целочисленные переменные i, j – счетчики циклов, t – временная.
По всем колесам ротора:
алг Поворот(аргрез цел таб Ротор[0 : МаксНомерКолеса, 0 : МаксНомерСимвола])
нач
цел i, j, t;
нц для i от 0 до МаксНомерКолеса
Первый символ по порядку i-м колесе сохраняется, затем все последующие элементы сдвигаются в порядке уменьшения номеров, и на место последнего помещается первый символ:
t := Ротор[i, 0];
нц для j от 1 до МаксНомерСимвола
Ротор[i, j - 1] := Ротор[i, j];
кц
Ротор[i, МаксНомерСимвола] := t;
кц
кон
Подпрограмма ГПСЧ возвращает вещественное псевдослучайное число по равномерному закону распределения. Используется линейный конгруэнтный генератор, коэффициенты взяты из [3], выбор малых значений коэффициентов обусловлен необходимостью невыхода за разрядную сетку:
алг вещ ГПСЧ
нач
СемяГПСЧ := mod(106 * СемяГПСЧ + 1283, 6075);
знач := СемяГПСЧ / 6075.0;
кон
Последняя подпрограмма АлфавитНомер возвращает номер символа в используемом для шифрования и дешифрования алфавите. Аргумент а содержит код искомого символа. Целочисленные переменные k, l играют роль индексов и счетчиков. Начальное значение возвращаемого индекса k – нуль.
алг цел АлфавитНомер(сим а)
нач
цел k, l;
k := 0;
По всем возможным символам в алфавите:
нц для l от 0 до МаксНомерСимвола
Если найден символ, то индекс фиксируется, цикл прерывается:
если Алфавит[l + 1] = а
то
k := l;
выход
все
кц
Индекс возвращается:
знач := k;
кон
Полный текст программы можно скачать на сайте журнала http://samag.ru.
Примерные результаты работы:
ААААААААМАМАМЫЛАРАМУАААААААА
ЧЩОФЭКФШВЩЮКЪЕТЪЖЗЛШЦОСЯШГОС
ААААААААМАМАМЫЛАРАМУАААААААА
ББББББББМАМАМЫЛАРАМУББББББББ
АЙЭИКЪЮЭВЩЮКЪЕТЪЖЗЛШЯЬИЛЬЖЛЫ
ББББББББМАМАМЫЛАРАМУББББББББ
ВВВВВВВВМАМАМЫЛАРАМУВВВВВВВВ
ЫЬЬГАДТЪВЩЮКЪЕТЪЖЗЛШЗЛФЕЛЁГЩ
ВВВВВВВВМАМАМЫЛАРАМУВВВВВВВВ
|
Поскольку система шифрования реализована на школьном алгоритмическом языке, то полученный результат позволяет, во-первых, впоследствии использовать многие другие высокоуровневые языки для этой системы, а во-вторых, ясно и наглядно продемонстрировать базовые конструкции языков программирования для решения нетривиальных задач всем заинтересованным в повышении уровня своей подготовки в области информатики и программирования.
- Жельников В. Криптография от папируса до компьютера. – М.: ABF, 1996. – 335 с. ISBN 5-87484-054-0.
- Текин В.В. Усовершенствованная версия «Энигмы». // «Мир ПК», № 6, 2007 г. – С. 64-65.
- Линейный конгруэнтный метод // Википедия. URL: https://ru.wikipedia.org/wiki/Линейный_конгруэнтный_метод (дата обращения: 07.08.2018).
- Ткаченко К.С. Программная реализация энигмоподобной системы в среде 1С. // «Системный администратор», № 4, 2017 г. – С.72-74. ISSN: 1813-5579. URL: http://samag.ru/archive/article/3414 (дата обращения: 07.08.2018).
Facebook
Мой мир
Вконтакте
Одноклассники
Google+
|