Модель шифра подстановки¶
Реализуем модель шифрования при помощи простой замены (моноалфавитный шифр).
Описание задачи¶
Шифры подстановки - еще один базовый блок современных систем шифрования. Его различные варианты применялись как в античности (шифр Цезаря, шифр простой замены), так и внутри реализаций самых современных алгоритмов, в качестве очередного этапа шифрования.
Шифр, который мы реализуем, называется шифром простой замены, и его работа сводится к созданию таблицы шифрования, в которой для каждой буквы открытого текста принята единственная буква шифротекста. Мы будем использовать только 33 символа - прописную часть символов кириллического алфавита (включая букву
Ё
).
Мы будем шифровать сообщения посимвольно, заменяя каждый символ на соответствующий ему символ шифротекста посредством таблицы подстановок.
Алфавит исходного сообщения состоит из 33 символов:
print( collect(1:33) )
Шифр-алфавит должен содержать все эти символы, но в псевдослучайном порядке:
target_order = shuffle( Xoshiro(1), 1:33 );
print( target_order )
Чтобы использовать эту таблицу в обратном направлении, нам нужно будет применить сортировку:
print( sortperm( target_order ) )
Обратите внимание, что при обращении к команде shuffle
мы каждый раз инициализируем генератор случайных чисел некоторым числом 1
. Это позволяет нам из раза в раз получать один и тот же псевдослучайный порядок сортировки значений (одинаковый для блока шифрования и для блока расшифровки).
Такая модель осуществляет шифрование и расшифровку сообщения.
Блоки перестановки¶
Моделей операции Перестановки
и Обратной перестановки
созданы при помощи блоков LookupTableND
, для удобства снабженных маской с элементами управления.
На лицевой стороне блока перестановки отражает две вещи:
- число
Seed
, которым мы инициализируем генератор случайных чисел - является ли перестановка прямой или обратной
Параметры блока перестановки устанавливаются в настройках его маски.
Запуск модели¶
Запустим модель средствами программного управления:
# Загрузим модель, если она еще не открыта на холсте
if "substitution_cipher_model" ∉ getfield.(engee.get_all_models(), :name)
engee.load( "$(@__DIR__)/substitution_cipher_model.engee");
end
model_data = engee.run( "substitution_cipher_model" );
source_message = collect(model_data["Сообщение"]).value
cipher_text = Int.(collect(model_data["Шифротекст"]).value)
received_message = Int.(collect(model_data["Расшифровка"]).value)
println( "Отправленное сообщение: ", source_message )
println( "Зашифрованное сообщение: ", cipher_text )
println( "Полученное сообщение: ", received_message )
alphabet_dict = Dict( zip( 1:33, "абвгдеёжзиёклмнопрстуфхцчшщъыьэюя" ))
print( "Расшифрованное сообщение: ", join( [alphabet_dict[d] for d in received_message], "" ) )
Поскольку в этой демонстрации сообщение передается по кругу, мы получили 11 букв, что может быть больше или меньше чем количество символов в исходном сообщении.
Заключение¶
Мы показали, как работает шифр подстановки на упрощенном примере, где сообщение отправляется в виде массива цифр, обозначающих позицию каждой буквы исходного сообщения в кириллическом алфавите (в нижнем регистре). Следующим шагом можно адаптировать модель для отправки по-байтовых сообщений, заменив код в блоках Подстановка
и Обратная подстановка
.