Шифр Цезаря

Первый шифр в нашем курсе — сдвиг букв по алфавиту. Им пользовался ещё Юлий Цезарь две тысячи лет назад.
Цезарь сдвигал каждую букву на 3 позиции вперёд, чтобы враги не прочитали его военные приказы.

Как устроен шифр Цезаря

Идея предельно проста: каждую букву сообщения заменяем на букву, стоящую на k позиций дальше в алфавите. Число k — это ключ. Например, при ключе 3 буква A превращается в D, B — в E, и так далее. Когда доходим до конца алфавита, продолжаем с начала (Z + 3 = C).

Шифруем на Python

Возьмём английский алфавит из 26 букв и реализуем сдвиг. Деление по модулю 26 (% 26) обеспечивает «закольцовывание» алфавита:

import string

alphabet = string.ascii_uppercase  # A..Z

def caesar_encrypt(text, key):
    result = ""
    for ch in text.upper():
        if ch in alphabet:
            i = (alphabet.index(ch) + key) % 26
            result += alphabet[i]
        else:
            result += ch
    return result

print(caesar_encrypt("HELLO WORLD", 3))

Вывод:

KHOOR ZRUOG

Расшифровка

Чтобы вернуть текст обратно, сдвигаем в другую сторону — то есть применяем тот же алгоритм с ключом -key:

import string
alphabet = string.ascii_uppercase

def caesar(text, key):
    result = ""
    for ch in text.upper():
        if ch in alphabet:
            result += alphabet[(alphabet.index(ch) + key) % 26]
        else:
            result += ch
    return result

secret = caesar("ATTACK AT DAWN", 7)
print("Зашифровано:", secret)
print("Расшифровано:", caesar(secret, -7))

Вывод:

Зашифровано: HAAHJR HA KHDU
Расшифровано: ATTACK AT DAWN

Почему его легко взломать

У шифра Цезаря всего 25 возможных ключей (сдвиг от 1 до 25). Это значит, что Ева может просто перебрать их все и посмотреть, какой вариант осмысленный. Такой перебор называют атакой «грубой силой» (brute force). Попробуем:

import string
alphabet = string.ascii_uppercase

def caesar(text, key):
    return "".join(
        alphabet[(alphabet.index(c) + key) % 26] if c in alphabet else c
        for c in text.upper()
    )

cipher = "KHOOR"
for key in range(1, 26):
    print(key, "->", caesar(cipher, -key))

Вывод:

1 -> JGNNQ
2 -> IFMMP
3 -> HELLO
4 -> GDKKN
...
25 -> LIPPS

Среди 25 вариантов глазами легко найти осмысленный — HELLO при ключе 3. Вот почему шифр Цезаря годится только для развлечения, а не для защиты настоящих секретов: пространство ключей слишком мало.

Проверьте себя
1. Сколько всего различных рабочих ключей у шифра Цезаря для латинского алфавита?
A3
B25
C26
DБесконечно много
2. Как называется взлом шифра простым перебором всех возможных ключей?
AЧастотный анализ
BАтака грубой силой (brute force)
CСоциальная инженерия
DХеширование
Поддержать проект