Загрузка данных
# ============================================================================
# ЗАДАЧА 1. Автоматический перебор шифра Цезаря
# ============================================================================
def caesar_bruteforce(ciphertext): # Создаём функцию для перебора шифра Цезаря, принимающую зашифрованный текст
for shift in range(26): # Запускаем цикл перебора всех 26 возможных сдвигов (от 0 до 25)
decrypted = "" # Создаём пустую строку для накопления расшифрованных символов
for char in ciphertext: # Перебираем каждый символ в исходном зашифрованном тексте
if char.isalpha(): # Проверяем, является ли текущий символ буквой (игнорируем пробелы и знаки)
base = ord('A') if char.isupper() else ord('a') # Определяем ASCII-код начала алфавита ('A' для заглавных, 'a' для строчных)
decrypted += chr((ord(char) - base - shift) % 26 + base) # Сдвигаем символ назад на величину shift, применяем модуль 26 для зацикливания алфавита и добавляем в результат
else: # Если символ не является буквой (например, пробел)
decrypted += char # Добавляем его в результат без изменений
print(f"Shift {shift:2d}: {decrypted}") # Выводим на экран вариант расшифровки для текущего сдвига
caesar_bruteforce("Wkh vhfuhw phvvdjh lv klgghq") # Вызываем функцию, передавая ей перехваченный шифротекст
# ============================================================================
# ЗАДАЧА 2. ROT13 и эвристика частотного анализа
# ============================================================================
import codecs # Подключаем стандартную библиотеку codecs для работы с различными кодировками и алгоритмами (в т.ч. ROT13)
cipher = "Gur cnffjbeq vf FhcreFrperg123" # Сохраняем перехваченный зашифрованный текст в переменную
decrypted = codecs.decode(cipher, 'rot_13') # Применяем алгоритм ROT13 для расшифровки (кодек 'rot_13' делает сдвиг на 13 позиций)
print(f"Расшифровано: {decrypted}") # Выводим результат расшифровки на экран
def is_english(text): # Объявляем вспомогательную функцию для эвристики: проверки, является ли текст английским
common = "etaoin shrdlu" # Задаём строку, содержащую самые часто встречающиеся буквы в английском языке
return sum(1 for c in text.lower() if c in common) / len(text) > 0.5 # Считаем процент частых букв в тексте; если он больше 50%, возвращаем True
if not is_english(cipher): # Проверяем: если исходный текст не проходит проверку на английский (значит, он зашифрован)
print("Похоже на ROT13:", codecs.decode(cipher, 'rot_13')) # Выводим сообщение и результат применения ROT13, так как это наиболее вероятный шифр
# ============================================================================
# ЗАДАЧА 3. Подбор ключа для однобайтного XOR-шифра
# ============================================================================
cipher = [0x2b, 0x3f, 0x3c, 0x3d, 0x20, 0x2e, 0x3f, 0x3c, 0x20, 0x3a, 0x3f, 0x3b] # Создаём список байтов шифротекста, записанных в шестнадцатеричном формате
target = "secret" # Задаём известное слово, которое по условию должно присутствовать в начале открытого текста
for key in range(256): # Запускаем цикл перебора всех возможных значений однобайтного ключа (от 0 до 255)
decrypted = ''.join(chr(b ^ key) for b in cipher) # Расшифровываем текст: применяем операцию исключающего ИЛИ (XOR) к каждому байту с текущим ключом и собираем символы в строку
if decrypted.startswith("secret"): # Проверяем, начинается ли полученная расшифрованная строка с искомого слова "secret"
print(f"Ключ: {key} (0x{key:02x})") # Если совпало, выводим найденный ключ в десятичном и шестнадцатеричном виде
print(f"Текст: {decrypted}") # Выводим полностью расшифрованный текст
break # Прерываем цикл перебора, так как правильный ключ уже найден
# ============================================================================
# ЗАДАЧА 4. Ручная реализация шифра Виженера
# ============================================================================
def vigenere(text, key, mode='encrypt'): # Определяем функцию для шифра Виженера, принимающую текст, ключ и режим работы (шифрование или дешифрование)
result = "" # Инициализируем пустую строку, в которую будем собирать результат
key = key.upper() # Приводим ключ к верхнему регистру для унификации вычислений
ki = 0 # Создаём счётчик для отслеживания текущей позиции в ключе (индекс буквы ключа)
for char in text.upper(): # Перебираем каждый символ исходного текста, предварительно переведя его в верхний регистр
if char.isalpha(): # Проверяем, является ли символ буквой (чтобы не шифровать пробелы и знаки)
shift = ord(key[ki % len(key)]) - ord('A') # Вычисляем величину сдвига: берём текущую букву ключа (с циклическим повтором через %) и находим её номер в алфавите
if mode == 'decrypt': # Если функция вызвана в режиме дешифрования
shift = -shift # Инвертируем направление сдвига (вычитаем вместо сложения)
result += chr((ord(char) - ord('A') + shift) % 26 + ord('A')) # Применяем сдвиг к символу с учётом зацикливания алфавита (модуль 26) и добавляем в результат
ki += 1 # Увеличиваем счётчик позиции в ключе, чтобы перейти к следующей букве ключа
else: # Если символ не является буквой
result += char # Добавляем его в результат без изменений
return result # Возвращаем итоговую зашифрованную или расшифрованную строку
plain = "PYTHONRULES" # Задаём исходный открытый текст для шифрования
key = "HACK" # Задаём ключ для шифра Виженера
enc = vigenere(plain, key, 'encrypt') # Вызываем функцию для получения шифротекста
dec = vigenere(enc, key, 'decrypt') # Вызываем функцию для обратного дешифрования полученного шифротекста
print(f"Открытый: {plain}") # Выводим исходный текст для наглядности
print(f"Шифротекст: {enc}") # Выводим полученный зашифрованный текст
print(f"Обратно: {dec}") # Выводим текст, полученный после дешифрования
assert dec == plain # Используем assert для проверки: убеждаемся, что дешифрованный текст в точности равен исходному
# ============================================================================
# ЗАДАЧА 5. Двойное кодирование Base64 + ROT13
# ============================================================================
import base64 # Подключаем модуль base64 для декодирования данных из формата Base64
# codecs уже импортирован выше
data = "U0dWc2JHOTBhR1Z5SUhObFkzSmxkQT09" # Сохраняем перехваченную строку, которая была закодирована дважды
step1 = base64.b64decode(data).decode() # Сначала декодируем строку из Base64 в байты, а затем преобразуем байты в обычную текстовую строку (по умолчанию UTF-8)
print(f"После Base64: {step1}") # Выводим промежуточный результат, полученный после снятия кодировки Base64
step2 = codecs.decode(step1, 'rot_13') # Затем применяем к промежуточной строке алгоритм ROT13 для её окончательной расшифровки
print(f"Итог: {step2}") # Выводим финальный расшифрованный результат