Шифр простой подстановки
Усложним идею Цезаря: пусть каждая буква заменяется на любую другую, а не просто сдвигается.
От сдвига к произвольной замене
В шифре Цезаря порядок букв сохраняется — мы лишь сдвигаем алфавит целиком. А что если перемешать буквы как угодно? Например, A заменяем на Q, B — на W, C — на E и так далее. Такое соответствие называется шифром простой подстановки, а сам перемешанный алфавит — это ключ.
Сколько теперь ключей
Ключ — это любая перестановка 26 букв. Их количество равно 26! (факториал):
import math
print("Число ключей:", math.factorial(26))Вывод:
Число ключей: 403291461126605635584000000
Это больше 4 на 10 в 26-й степени — астрономическое число. Перебрать их грубой силой невозможно даже на самом мощном компьютере. Казалось бы, шифр надёжен. Но это иллюзия, и скоро мы увидим почему.
Шифруем подстановкой
import string
plain = string.ascii_uppercase
cipher = "QWERTYUIOPASDFGHJKLZXCVBNM" # перемешанный алфавит = ключ
table = str.maketrans(plain, cipher)
message = "MEET ME AT MIDNIGHT"
encrypted = message.translate(table)
print("Зашифровано:", encrypted)
# обратная таблица для расшифровки
back = str.maketrans(cipher, plain)
print("Расшифровано:", encrypted.translate(back))Вывод:
Зашифровано: DTTZ DT QZ DOEFOUIZ Расшифровано: MEET ME AT MIDNIGHT
Почему огромное число ключей не спасает
Главная слабость подстановки в том, что одна и та же буква всегда заменяется одинаково. Буква E в английском тексте встречается чаще всех, и какой бы символ её ни заменял, этот символ тоже будет встречаться чаще всех в шифр-тексте. Получается, частоты букв «просвечивают» сквозь шифр. Именно это используют для взлома — и об этом следующий урок.
Маленькое наблюдение
from collections import Counter
text = "DTTZ DT QZ DOEFOUIZ".replace(" ", "")
print(Counter(text).most_common(3))Вывод:
[('D', 3), ('T', 3), ('Z', 3)]Видишь? Даже на коротком сообщении буквы повторяются неравномерно. На длинном тексте этот перекос станет явной подсказкой для взломщика.