Реалізуймо простий шифр зсуву, схожий на шифр Цезаря, а також надійніший шифр підстановки.
«Якщо йому треба було сказати щось конфіденційне, він писав це шифром, тобто так змінював порядок літер алфавіту, що з них не можна було скласти жодного слова. Якщо хтось захоче розшифрувати ці послання й зрозуміти їхній зміст, він має підставити четверту літеру алфавіту, а саме D, замість A, і так само з рештою.»
Шифри - це прості алгоритми, які дають змогу зробити текст менш читабельним, але при цьому його легко розшифрувати. Вони вразливі до багатьох видів криптоаналізу, але Цезарю пощастило: його вороги не були криптоаналітиками.
Шифр Цезаря використовували для деяких послань Юлія Цезаря, які надсилали в далекі краї. Цезар знав, що цей шифр не дуже добрий, але в цьому в нього був один союзник: майже ніхто не вмів добре читати. Тож навіть кількох зсунутих літер було досить, щоб люди не впізнавали ті небагато слів, які все ж знали.
Ваше завдання - створити простий шифр зсуву, схожий на шифр Цезаря. Це зображення - чудовий приклад шифру Цезаря:
![]()
Наприклад:
Якщо подати "iamapandabear" на вхід функції кодування, вона повертає шифр "ldpdsdqgdehdu". Достатньо заплутано, щоб зберегти наше повідомлення в таємниці під час передавання.
Коли "ldpdsdqgdehdu" потрапляє у функцію декодування, вона повертає початковий "iamapandabear", і початкове повідомлення можна прочитати.
Шифри зсуву швидко втрачають користь, щойно командир супротивника їх розгадує. Тож натомість спробуймо скористатися шифром підстановки. Спробуймо змінити код так, щоб можна було задавати ключ і використовувати його як величину зсуву.
Ось приклад:
Якщо взяти ключ "aaaaaaaaaaaaaaaaaa", кодування рядка тексту (англ. string) "iamapandabear" поверне початковий "iamapandabear".
Якщо взяти ключ "ddddddddddddddddd", кодування нашого рядка тексту "iamapandabear" поверне заплутаний "ldpdsdqgdehdu"
У наведеному прикладі ми задали a = 0 як значення ключа. Тож коли до відкритого тексту додати ключ, на виході отримаємо те саме повідомлення. Отже, "aaaa" - не найкращий ключ. Але якщо задати ключ "dddd", отримаємо те саме, що й у шифрі Цезаря.
Найслабша ланка будь-якого шифру - людина. Зробімо шифр підстановки трохи стійкішим до помилок: додаймо джерело випадковості і подбаймо, щоб ключ містив лише малі літери.
Якщо ключ узагалі не задано, згенеруймо справді випадковий ключ завдовжки щонайменше 100 малих літер.
Шифри зсуву працюють, роблячи текст трохи дивним, але вони вразливі до частотного аналізу. Шифри підстановки частково це вирішують, але все одно дуже вразливі, коли ключ короткий або коли збережено пробіли. Згодом ми побачимо один із розвʼязків цієї проблеми у вправі "crypto-square".
Якщо ми хочемо просунутися в цій царині далі, питання починаються з того, як безпечно обмінюватися ключами. Щоб побачити одну з перших реалізацій цієї схеми, загляньмо до статті про Діффі-Геллмана у Вікіпедії.
Спробуйте використати арифметичні операції, як-от остачу від ділення, щоб загортати індекси, коли вони виходять за межі. Класи Character і String теж стануть у пригоді.