Перейти к содержимому
New

DeepSeek V4.1 Flash free for 7 days: 10M tokens a day after a top-up of $10 or more. Until Nov 30.

How it works

Что такое шифр Цезаря: простой пример и почему он небезопасен

Шифр Цезаря сдвигает каждую букву на фиксированное число позиций. Зашифруйте HELLO в KHOOR вручную, расшифруйте обратно и посмотрите, почему он ненадёжен.

Начальный3 мин чтенияАвтор: NotHoly

Шифр Цезаря — шифр подстановки. Он заменяет каждую букву другой, отстоящей от неё на фиксированное число позиций в алфавите. Сдвиньте каждую букву на три позиции вперёд, и HELLO превратится в KHOOR. Название происходит от имени Юлия Цезаря, который, по преданию, использовал такой сдвиг в своих посланиях. Шифр достаточно прост, чтобы работать с ним вручную, и из-за этой простоты он почти не даёт защиты.

Шифрование вручную

Запишите алфавит в одну строку. Во второй строке запишите тот же алфавит со сдвигом на три, с переходом на начало после Z:

text
Plain:  ABCDEFGHIJKLMNOPQRSTUVWXYZ
Shift:  DEFGHIJKLMNOPQRSTUVWXYZABC

Чтобы зашифровать текст, найдите каждую букву открытого текста в верхней строке и выпишите букву прямо под ней. H становится K, E становится H, L становится O, а O становится R. В итоге HELLO превращается в KHOOR. Ключ — величина сдвига, здесь 3.

Пробелов, цифр и знаков препинания нет в алфавите от A до Z. Учебная версия может оставлять их без изменений, и код на Python ниже так и делает.

Расшифровка

Расшифровка — та же таблица, прочитанная в обратном направлении. Сдвиньте каждую букву на три позиции назад, что равносильно сдвигу на 23 позиции вперёд:

text
KHOOR  →  HELLO

При заданном ключе каждой букве открытого текста соответствует ровно одна буква шифртекста, и обратное соответствие так же однозначно. Поэтому шифр можно обратить, если известен ключ.

Отрицательные и большие сдвиги

В английском алфавите 26 букв, поэтому сдвиги повторяются каждые 26 позиций. Сдвиг на 29 даёт тот же результат, что и сдвиг на 3:

text
29 mod 26 = 3

Сдвиг на −3 даёт тот же результат, что и сдвиг на 23. В коде берите сдвиг по модулю 26, тогда подойдёт любое целое число.

Короткая версия на Python

Эта функция сдвигает только буквы от A до Z и от a до z, всё остальное оставляет без изменений и переходит на начало алфавита по модулю 26. Для преобразования между буквами и числами она использует ord и chr:

python
def caesar(text, shift):
    out = []
    for ch in text:
        if ch.isascii() and ch.isalpha():
            base = ord('A') if ch.isupper() else ord('a')
            out.append(chr((ord(ch) - base + shift) % 26 + base))
        else:
            out.append(ch)
    return ''.join(out)

print(caesar("HELLO", 3))
print(caesar("KHOOR", -3))
print(caesar("KHOOR", 23))
print(caesar("HELLO", 29))
print(caesar("ATTACK AT DAWN", 3))
print(caesar(caesar("Hello, World!", 13), 13))
print(caesar("Hello, World!", 13))
print(caesar("hello, world", 3))
print(caesar("KHOOR", 26 - 3) == caesar("KHOOR", -3))
print(sum(1 for s in range(1, 26) if caesar("KHOOR", s) == "HELLO"))
print(caesar("HELLO", 3) == caesar("HELLO", 29))

Вывод этого скрипта:

text
KHOOR
HELLO
HELLO
KHOOR
DWWDFN DW GDZQ
Hello, World!
Uryyb, Jbeyq!
khoor, zruog
True
1
True

Вывод подтверждает предыдущие разделы. Сдвиги −3 и 23 совпадают, 3 и 29 тоже. Из сдвигов от 1 до 25 только один превращает KHOOR обратно в HELLO. Двукратное применение сдвига 13 возвращает исходный текст: это случай ROT13, описанный ниже.

Почему шифр Цезаря небезопасен

В алфавите из 26 букв есть всего 25 сдвигов, которые меняют текст. Атакующий может перебрать их все и посмотреть, какой результат читается. В английском тексте читаемый результат легко заметить, поэтому атака почти не требует усилий.

Частоты букв тоже сохраняются при сдвиге. В английском E встречается часто, а Z редко, поэтому шифртекст, где одна буква появляется намного чаще остальных, даёт сильную подсказку. Даже без перебора всех сдвигов подсчёт букв указывает на ключ.

Шифр полезен, чтобы освоить терминологию криптографии: открытый текст, шифртекст, ключ, подстановка и перебор. Защищать пароли, данные клиентов, API-ключи или личные файлы им нельзя. Настоящее шифрование использует стандартизованные алгоритмы, правильно сгенерированные ключи и аккуратное управление ключами. Формальные определения этой области даёт запись о криптографии в глоссарии NIST.

Шифр Цезаря и ROT13

ROT13 — шифр Цезаря со сдвигом 13. Он сам себе обратный: двукратное применение возвращает исходный текст, потому что 13 + 13 = 26, а полный круг по алфавиту ничего не меняет. Результат ROT13 для Hello, World! — Uryyb, Jbeyq!, как показано выше.

ROT13 применяют, чтобы спрятать спойлеры или развязки шуток от случайного взгляда. Настоящей защиты он не даёт: любой, кто знает метод, прочитает текст за секунды.

Попробуйте сами

Зашифруйте ATTACK AT DAWN вручную со сдвигом 3, сохранив пробелы. Сравните свой ответ с этим:

text
DWWDFN DW GDZQ

Затем измените сдвиг в функции на Python и запустите её на том же тексте. Попробуйте сдвиг 0, сдвиг 26 и сдвиг 13 и предскажите каждый результат до запуска. Текст для проверки берите синтетический или свой собственный, а упражнение выполняйте на своей машине.

Когда будете готовы, в следующей статье, шифр Цезаря на Python, эта функция дополняется обработкой ввода и тестами.

Что ещё почитать: запись о криптографии в глоссарии NIST и документацию Python по ord и chr.

Источники

  1. NIST Cryptography Glossary
  2. Python documentation: Built-in Functions (ord, chr)

Ещё по теме: Криптография

Криптография

Пароли и хеширование с Argon2id

Почему быстрые хеши не годятся для паролей, что делают соль и коэффициент нагрузки и как хешировать и проверять пароли с Argon2id в Python через argon2-cffi.

Средний9 мин чтения