Skip to main content

Частотный анализ

🎯 ЦЕЛИ И ЗАДАЧИ ИЗУЧЕНИЯ

Образовательные цели:

  • Математические: освоение статистических методов, работа с большими данными
  • Информатические: алгоритмизация, программирование, автоматизация вычислений
  • Исторические: понимание эволюции криптографии и роли математики в ней

Развивающие задачи:

  • Аналитическое мышление и поиск закономерностей
  • Исследовательские навыки и работа с первоисточниками
  • Междисциплинарные связи: математика ↔ лингвистика ↔ информатика

Практические компетенции:

  • Автоматизированный анализ текстов
  • Оценка стойкости криптосистем
  • Программирование криптоаналитических алгоритмов

📚 ТЕОРЕТИЧЕСКИЕ ОСНОВЫ

1.1 Фундаментальная идея

Частотный анализ — статистический метод взлома шифров, основанный на неравномерном распределении букв в естественных языках.

Математическая формулировка:

Пусть L = {l₁, l₂, ..., lₙ} — алфавит языка, T — текст длины N.
Частота буквы lᵢ в тексте: f(lᵢ) = count(lᵢ, T) / N

Ключевая гипотеза:

Для любого достаточно длинного текста на данном языке распределение частот {f(lᵢ)} стремится к характерному для языка распределению {pᵢ}.

1.2 Историческая перспектива

ПериодДостижениеАвторЗначение
IX векПервое описание методаАль-КиндиОснование криптоанализа
1843Популяризация в литературеЭдгар ПоОбщественное признание
1863Атака на ВиженераКасискиПреодоление “нераскрываемого”
XX векАвтоматизацияКомпьютерыМассовое применение

1.3 Лингвистические основы

Закон Ципфа для букв:

Если буквы упорядочить по убыванию частот, то частота k-й буквы приблизительно равна:

f(k) ≈ C / k^α

где C — константа, α ≈ 1 для большинства языков.

Статистический портрет русского языка:

Топ-10 букв:

  1. О — 10.97% (гласная, в основах слов)
  2. Е — 8.45% (гласная, в окончаниях)
  3. А — 8.01% (гласная, универсальная)
  4. И — 7.35% (гласная, в предлогах)
  5. Н — 6.70% (согласная, в окончаниях)
  6. Т — 6.26% (согласная, в глаголах)
  7. С — 5.53% (согласная, в предлогах)
  8. Р — 4.97% (согласная, в корнях)
  9. В — 4.33% (согласная, предлог)
  10. Л — 4.40% (согласная, в корнях)

Редкие буквы: Ъ (0.04%), Ё (0.04%), Э (0.32%)


🧮 МАТЕМАТИЧЕСКИЙ АППАРАТ

2.1 Основные статистические характеристики

Индекс совпадений (Index of Coincidence):

IC = Σᵢ₌₁ⁿ [fᵢ(fᵢ-1)] / [N(N-1)]

где fᵢ — количество вхождений i-й буквы, N — длина текста.

Интерпретация:

  • Русский текст: IC ≈ 0.0553
  • Английский текст: IC ≈ 0.0667
  • Случайный текст: IC ≈ 1/размер_алфавита

Хи-квадрат критерий соответствия:

χ² = Σᵢ₌₁ⁿ (Oᵢ - Eᵢ)² / Eᵢ

где Oᵢ — наблюдаемая частота, Eᵢ — ожидаемая частота.

2.2 Алгоритм взлома моноалфавитного шифра

АЛГОРИТМ FrequencyAttack(ciphertext):
1. frequencies = CountLetters(ciphertext)
2. sorted_freq = Sort(frequencies, descending=True)
3. russian_freq = ['О', 'Е', 'А', 'И', 'Н', 'Т', ...]
4. 
5. FOR each possible_shift in [0..32]:
6.     decrypted = CaesarDecrypt(ciphertext, possible_shift)
7.     score = CalculateScore(decrypted, russian_freq)
8.     IF score > best_score:
9.         best_shift = possible_shift
10.        best_text = decrypted
11.
12. RETURN best_text, best_shift

2.3 Метод Касиски для полиалфавитных шифров

Математическое обоснование:

Если в открытом тексте повторяющийся фрагмент s встречается на позициях i и j, и при этом (j-i) mod L = 0 (где L — длина ключа), то зашифрованные фрагменты будут идентичны.

Алгоритм поиска длины ключа:

АЛГОРИТМ KasiskiMethod(ciphertext):
1. repeats = FindRepeats(ciphertext, min_length=3)
2. distances = []
3. FOR each repeat in repeats:
4.     FOR each pair of positions (p1, p2) in repeat:
5.         distances.append(p2 - p1)
6. 
7. common_factors = FindCommonFactors(distances)
8. key_length_candidates = common_factors
9. 
10. FOR each L in key_length_candidates:
11.     ic_score = CalculateAverageIC(ciphertext, L)
12.     IF ic_score > threshold:
13.         RETURN L

🎯 ПРАКТИЧЕСКИЕ МЕТОДЫ ВЗЛОМА

3.1 Детальный разбор взлома шифра Цезаря

Пример для анализа:

Зашифрованный текст:
ДФХСЦЦУГЩУЦФКУ ГЩДУДЪУЖКЦСУЦЪСЙ

Шаг 1: Подсчет частот

def count_frequencies(text):
    freq = {}
    clean_text = ''.join(c.upper() for c in text if c.isalpha())
    
    for char in clean_text:
        freq[char] = freq.get(char, 0) + 1
    
    total = len(clean_text)
    return {char: count/total*100 for char, count in freq.items()}

Результат для примера:

  • Ц: 4 вхождения (13.33%) ← Самая частая
  • Г, С, У, Д: по 3 вхождения (10.00%)
  • Ф, Щ: по 2 вхождения (6.67%)

Шаг 2: Формулировка гипотез

  1. Гипотеза 1: Ц → О (самая частая в русском)

    • Сдвиг: (Ц - О) = (24 - 15) = 9
    • Проверка: Ц→О, Д→У, Ф→Ч, Х→Ъ… → “УЧОТТНУЪЩУТЧПН” ❌
  2. Гипотеза 2: Ц → Е (вторая по частоте)

    • Сдвиг: (24 - 6) = 18
    • Проверка: Ц→Е, Д→М, Ф→П… → “МПОВЕЕНКОЛЕПНК” ❌
  3. Гипотеза 3: Г → О

    • Сдвиг: (4 - 15) = -11 ≡ 22 (mod 33)
    • Проверка: Д→Ь, Ф→О, Х→С… → “ШОЧЬЮЮРОЧРСО…” ❌

Шаг 3: Системный перебор

def brute_force_caesar(ciphertext):
    best_score = 0
    best_shift = 0
    
    for shift in range(33):
        decrypted = caesar_decrypt(ciphertext, shift)
        score = calculate_russian_score(decrypted)
        
        if score > best_score:
            best_score = score
            best_shift = shift
    
    return caesar_decrypt(ciphertext, best_shift), best_shift

Результат: При сдвиге 16 получаем “ИНФОРМАЦИОННЫЕ ТЕХНОЛОГИИ

3.2 Продвинутый пример: Взлом Виженера

Исходные данные:

ЧОПЬЖЕМЫЕЧИЭЕГЩДЛВПДЯЙВЮЧБТЬМОЩФФЦБЛЛСЪВЙЩКНМЪЮРЫБ
ЕСНСУСКБЗФПФЮЩЗЭИЖТНЙИЬЩЮЪЩКДЪИОЦЩЩВЪЧУАГКНХНЫЙЯКО
ЪИРЙФКЛМЪЪЖЬТЬЬФЮЧЫЁЙФНЫЙЫЁЙЧЧСЙЮЧХМСУЙЮПВИНСЦЬТДМ
КПДЭЫЕЧЩПЦЫЮЮЧИАЧЦШУЫМЭУПЫЕЩНЭТЬШАЮЧБТНАИФЗИТЬЛЛСЪ
ВЙЩУПЫЮЮЛЦПНМЗЭЧНЫЬЧИЯРЦЬМЫФК

Этап 1: Метод Касиски

Поиск повторяющихся фрагментов:

def find_repeats(text, min_length=3, max_length=5):
    repeats = {}
    text_length = len(text)
    
    for length in range(min_length, max_length + 1):
        for i in range(text_length - length + 1):
            fragment = text[i:i+length]
            
            if fragment not in repeats:
                repeats[fragment] = []
            repeats[fragment].append(i)
    
    # Оставляем только повторяющиеся
    return {frag: positions for frag, positions in repeats.items() 
            if len(positions) > 1}

Найденные повторы:

  • ЮЧБТ: позиции 23, 213 → расстояние 190
  • ЬЛЛ: позиции 47, 237 → расстояние 190
  • ЮЧ: позиции 23, 62, 117, 154, 194… → расстояния 39, 55, 37, 40…

Анализ расстояний:

  • 190 = 2 × 5 × 19
  • НОД(39, 55, 37, 40) = 1 (не информативно)
  • Кандидаты длины ключа: {2, 5, 10, 19}

Этап 2: Индекс совпадений

def calculate_ic(text):
    frequencies = {}
    for char in text:
        frequencies[char] = frequencies.get(char, 0) + 1
    
    n = len(text)
    ic = sum(f * (f - 1) for f in frequencies.values()) / (n * (n - 1))
    return ic

def test_key_length(ciphertext, length):
    groups = [''] * length
    for i, char in enumerate(ciphertext):
        groups[i % length] += char
    
    average_ic = sum(calculate_ic(group) for group in groups) / length
    return average_ic

Результаты тестирования:

  • L=2: IC≈0.040
  • L=5: IC≈0.045
  • L=6: IC≈0.054 ← Ближе всего к 0.0553!
  • L=10: IC≈0.048
  • L=19: IC≈0.052

Вывод: Длина ключа = 6

Этап 3: Частотный анализ групп

Разбиваем текст на 6 групп и анализируем каждую как шифр Цезаря:

Группа 0 (позиции 0, 6, 12, …):

ЧЭЯОЩСГИЪЖСЫЭЭЫ...

Самая частая: Ч → предполагаем О → сдвиг 9 → ключ[0] = ‘И’

Группа 1 (позиции 1, 7, 13, …):

ОФЙФФЮЩЩРЬЮЮУП...

Самая частая: Ф → предполагаем О → сдвиг 13 → ключ[1] = ‘Н’

Аналогично для остальных групп…

Итоговый ключ: ИНФОРМ

Этап 4: Расшифровка

def vigenere_decrypt(ciphertext, key):
    alphabet = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'
    result = ''
    key_length = len(key)
    
    for i, char in enumerate(ciphertext):
        if char in alphabet:
            cipher_pos = alphabet.index(char)
            key_pos = alphabet.index(key[i % key_length])
            plain_pos = (cipher_pos - key_pos) % 33
            result += alphabet[plain_pos]
    
    return result

Результат:

СОВРЕМЕННЫЕ КРИПТОГРАФИЧЕСКИЕ МЕТОДЫ ЗАЩИТЫ ИНФОРМАЦИИ 
ОСНОВАНЫ НА СЛОЖНЫХ МАТЕМАТИЧЕСКИХ АЛГОРИТМАХ КОТОРЫЕ 
ОБЕСПЕЧИВАЮТ КОНФИДЕНЦИАЛЬНОСТЬ И ЦЕЛОСТНОСТЬ ДАННЫХ 
ПРИ ПЕРЕДАЧЕ ПО СЕТЯМ И ХРАНЕНИИ В БАЗАХ ДАННЫХ

💻 ПРОГРАММИРОВАНИЕ РЕШЕНИЙ

4.1 Полная реализация криптоаналитического пакета

import re
from collections import Counter
import math

class FrequencyAnalyzer:
    
    # Эталонные частоты для русского языка
    RUSSIAN_FREQ = {
        'О': 10.97, 'Е': 8.45, 'А': 8.01, 'И': 7.35, 'Н': 6.70,
        'Т': 6.26, 'С': 5.53, 'Р': 4.97, 'В': 4.33, 'Л': 4.40,
        'К': 3.49, 'М': 3.21, 'Д': 2.98, 'П': 2.81, 'У': 2.62,
        # ... остальные буквы
    }
    
    RUSSIAN_IC = 0.0553
    ALPHABET = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'
    
    def __init__(self):
        self.alphabet_size = len(self.ALPHABET)
    
    def clean_text(self, text):
        """Очистка текста: только русские буквы, верхний регистр"""
        return re.sub(r'[^А-ЯЁ]', '', text.upper())
    
    def calculate_frequencies(self, text):
        """Подсчет частот букв в процентах"""
        clean = self.clean_text(text)
        if not clean:
            return {}
        
        counter = Counter(clean)
        total = len(clean)
        return {char: (count / total) * 100 
                for char, count in counter.items()}
    
    def calculate_ic(self, text):
        """Вычисление индекса совпадений"""
        clean = self.clean_text(text)
        n = len(clean)
        if n <= 1:
            return 0
        
        counter = Counter(clean)
        ic = sum(count * (count - 1) 
                for count in counter.values()) / (n * (n - 1))
        return ic
    
    def chi_squared_score(self, observed_freq):
        """Хи-квадрат оценка похожести на русский язык"""
        score = 0
        for char in self.ALPHABET:
            observed = observed_freq.get(char, 0)
            expected = self.RUSSIAN_FREQ.get(char, 0.1)
            score += (observed - expected) ** 2 / expected
        return score
    
    def break_caesar(self, ciphertext):
        """Взлом шифра Цезаря"""
        clean_cipher = self.clean_text(ciphertext)
        best_score = float('inf')
        best_shift = 0
        best_text = ""
        
        for shift in range(self.alphabet_size):
            # Расшифровка с текущим сдвигом
            decrypted = self._caesar_decrypt(clean_cipher, shift)
            
            # Оценка качества расшифровки
            freq = self.calculate_frequencies(decrypted)
            score = self.chi_squared_score(freq)
            
            if score < best_score:
                best_score = score
                best_shift = shift
                best_text = decrypted
        
        return {
            'text': best_text,
            'shift': best_shift,
            'score': best_score,
            'key': self.ALPHABET[best_shift]
        }
    
    def _caesar_decrypt(self, text, shift):
        """Расшифровка Цезаря с заданным сдвигом"""
        result = ""
        for char in text:
            old_pos = self.ALPHABET.index(char)
            new_pos = (old_pos - shift) % self.alphabet_size
            result += self.ALPHABET[new_pos]
        return result
    
    def find_key_length_kasiski(self, ciphertext, min_repeat=3):
        """Поиск длины ключа методом Касиски"""
        clean = self.clean_text(ciphertext)
        repeats = {}
        
        # Поиск повторяющихся фрагментов
        for length in range(min_repeat, min(len(clean)//2, 8)):
            for i in range(len(clean) - length):
                fragment = clean[i:i+length]
                if fragment not in repeats:
                    repeats[fragment] = []
                repeats[fragment].append(i)
        
        # Анализ расстояний между повторами
        distances = []
        for fragment, positions in repeats.items():
            if len(positions) > 1:
                for i in range(len(positions)-1):
                    distance = positions[i+1] - positions[i]
                    distances.append(distance)
        
        if not distances:
            return []
        
        # Поиск общих делителей
        factors = set()
        for distance in distances:
            factors.update(self._get_factors(distance))
        
        # Фильтрация разумных длин ключа
        return sorted([f for f in factors if 2 <= f <= 20])
    
    def _get_factors(self, n):
        """Получение всех делителей числа"""
        factors = []
        for i in range(2, int(n**0.5) + 1):
            if n % i == 0:
                factors.extend([i, n // i])
        return list(set(factors))
    
    def test_key_length_ic(self, ciphertext, length):
        """Тест длины ключа по индексу совпадений"""
        clean = self.clean_text(ciphertext)
        groups = [''] * length
        
        for i, char in enumerate(clean):
            groups[i % length] += char
        
        average_ic = sum(self.calculate_ic(group) 
                        for group in groups) / length
        return average_ic
    
    def break_vigenere(self, ciphertext):
        """Полный взлом шифра Виженера"""
        # Этап 1: Поиск длины ключа
        candidates = self.find_key_length_kasiski(ciphertext)
        
        if not candidates:
            candidates = range(2, 21)  # Перебор по умолчанию
        
        # Тестирование кандидатов по IC
        best_length = 0
        best_ic = 0
        
        for length in candidates:
            ic = self.test_key_length_ic(ciphertext, length)
            if ic > best_ic and ic > 0.045:  # Порог для русского
                best_ic = ic
                best_length = length
        
        if best_length == 0:
            return None
        
        # Этап 2: Восстановление ключа
        clean = self.clean_text(ciphertext)
        key = ""
        
        for i in range(best_length):
            # Группа символов для i-й позиции ключа
            group = clean[i::best_length]
            
            # Взлом группы как шифра Цезаря
            result = self.break_caesar(group)
            key += self.ALPHABET[result['shift']]
        
        # Этап 3: Расшифровка полного текста
        decrypted = self._vigenere_decrypt(clean, key)
        
        return {
            'text': decrypted,
            'key': key,
            'key_length': best_length,
            'ic': best_ic
        }
    
    def _vigenere_decrypt(self, text, key):
        """Расшифровка Виженера"""
        result = ""
        key_length = len(key)
        
        for i, char in enumerate(text):
            char_pos = self.ALPHABET.index(char)
            key_pos = self.ALPHABET.index(key[i % key_length])
            decrypted_pos = (char_pos - key_pos) % self.alphabet_size
            result += self.ALPHABET[decrypted_pos]
        
        return result

# Пример использования
if __name__ == "__main__":
    analyzer = FrequencyAnalyzer()
    
    # Тест на шифре Цезаря
    caesar_cipher = "ДФХСЦЦУГЩУЦФКУ ГЩДУДЪУЖКЦСУЦЪСЙ"
    result = analyzer.break_caesar(caesar_cipher)
    print(f"Цезарь взломан: {result['text']}")
    print(f"Ключ: {result['key']} (сдвиг {result['shift']})")
    
    # Тест на шифре Виженера
    vigenere_cipher = """ЧОПЬЖЕМЫЕЧИЭЕГЩДЛВПДЯЙВЮЧБТЬМОЩФФЦБЛЛСЪВ
                        ЙЩКНМЪЮРЫБЕСНСУСКБЗФПФЮЩЗЭИЖТНЙИЬЩЮЪЩКДЪ
                        ИОЦЩЩВЪЧУАГКНХНЫЙЯКОЪИРЙФКЛМЪЪЖЬТЬЬФЮЧЫЁ
                        ЙФНЫЙЫЁЙЧЧСЙЮЧХМСУЙЮПВИНСЦЬТДМКПДЭЫЕЧЩПЦ
                        ЫЮЮЧИАЧЦШУЫМЭУПЫЕЩНЭТЬШАЮЧБТНАИФЗИТЬЛЛСЪ
                        ВЙЩУПЫЮЮЛЦПНМЗЭЧНЫЬЧИЯРЦЬМЫФК"""
    
    result = analyzer.break_vigenere(vigenere_cipher)
    if result:
        print(f"Виженер взломан!")
        print(f"Ключ: {result['key']}")
        print(f"Длина ключа: {result['key_length']}")
        print(f"Текст: {result['text'][:100]}...")

4.2 Визуализация результатов

import matplotlib.pyplot as plt
import numpy as np

class CryptographyVisualizer:
    
    def __init__(self, analyzer):
        self.analyzer = analyzer
        plt.rcParams['font.family'] = ['DejaVu Sans']
    
    def plot_frequency_comparison(self, text, title="Частотный анализ"):
        """Сравнение частот текста с эталонными"""
        frequencies = self.analyzer.calculate_frequencies(text)
        
        # Подготовка данных
        letters = list(self.analyzer.ALPHABET)
        observed = [frequencies.get(letter, 0) for letter in letters]
        expected = [self.analyzer.RUSSIAN_FREQ.get(letter, 0) 
                   for letter in letters]
        
        x = np.arange(len(letters))
        width = 0.35
        
        fig, ax = plt.subplots(figsize=(15, 8))
        bars1 = ax.bar(x - width/2, observed, width, 
                      label='Наблюдаемые', alpha=0.8, color='steelblue')
        bars2 = ax.bar(x + width/2, expected, width, 
                      label='Эталонные (русский)', alpha=0.8, color='coral')
        
        ax.set_xlabel('Буквы')
        ax.set_ylabel('Частота (%)')
        ax.set_title(title)
        ax.set_xticks(x)
        ax.set_xticklabels(letters)
        ax.legend()
        ax.grid(True, alpha=0.3)
        
        plt.xticks(rotation=0)
        plt.tight_layout()
        plt.show()
    
    def plot_ic_analysis(self, ciphertext, max_length=20):
        """График индекса совпадений для разных длин ключа"""
        lengths = list(range(1, max_length + 1))
        ic_values = [self.analyzer.test_key_length_ic(ciphertext, l) 
                    for l in lengths]
        
        plt.figure(figsize=(12, 6))
        plt.plot(lengths, ic_values, 'bo-', linewidth=2, markersize=8)
        plt.axhline(y=self.analyzer.RUSSIAN_IC, color='red', 
                   linestyle='--', label=f'Эталон (русский): {self.analyzer.RUSSIAN_IC}')
        plt.axhline(y=1/33, color='gray', linestyle=':', 
                   label='Случайный текст: 0.030')
        
        plt.xlabel('Длина ключа')
        plt.ylabel('Индекс совпадений')
        plt.title('Определение длины ключа по индексу совпадений')
        plt.legend()
        plt.grid(True, alpha=0.3)
        plt.show()
        
        # Возврат наиболее вероятной длины
        best_length = lengths[np.argmax(ic_values)]
        return best_length
    
    def plot_caesar_bruteforce(self, ciphertext):
        """Визуализация перебора всех сдвигов для Цезаря"""
        clean = self.analyzer.clean_text(ciphertext)
        shifts = list(range(33))
        scores = []
        
        for shift in shifts:
            decrypted = self.analyzer._caesar_decrypt(clean, shift)
            freq = self.analyzer.calculate_frequencies(decrypted)
            score = self.analyzer.chi_squared_score(freq)
            scores.append(score)
        
        plt.figure(figsize=(12, 6))
        plt.plot(shifts, scores, 'ro-', linewidth=2, markersize=6)
        
        best_shift = shifts[np.argmin(scores)]
        plt.axvline(x=best_shift, color='green', linestyle='--', 
                   label=f'Лучший сдвиг: {best_shift}')
        
        plt.xlabel('Сдвиг')
        plt.ylabel('Хи-квадрат оценка (меньше = лучше)')
        plt.title('Поиск оптимального сдвига для шифра Цезаря')
        plt.legend()
        plt.grid(True, alpha=0.3)
        plt.show()
        
        return best_shift

🔬 ИССЛЕДОВАТЕЛЬСКИЕ ЗАДАНИЯ

5.1 Лабораторная работа №1: “Языковые отпечатки”

Цель:

Исследовать частотные характеристики различных текстов и авторов.

Задания:

Базовый уровень:

  1. Возьмите три различных текста на русском языке (новостная статья, художественная литература, техническая документация)
  2. Для каждого текста постройте частотную диаграмму букв
  3. Сравните полученные результаты с эталонными частотами
  4. Объясните различия

Продвинутый уровень:

  1. Выберите произведения трех разных авторов (например, Пушкин, Толстой, Достоевский)
  2. Проанализируйте частотные характеристики их стилей
  3. Попробуйте определить автора неизвестного текста по частотному “отпечатку”
  4. Исследуйте, как длина текста влияет на точность анализа

Олимпиадный уровень:

  1. Разработайте алгоритм автоматического определения языка текста по частотам
  2. Протестируйте его на текстах, написанных на русском, английском, немецком языках
  3. Исследуйте влияние транслитерации на частотные характеристики

Ожидаемые результаты:

  • Графики частотного распределения
  • Таблицы сравнительного анализа
  • Выводы о применимости метода
  • Программный код реализации

5.2 Проектная работа: “Эволюция криптографии”

Исследовательские направления:

1. Исторический анализ

  • Проследите развитие методов частотного анализа от Аль-Кинди до современности
  • Изучите, как менялись подходы к защите от частотного анализа
  • Создайте временную шкалу ключевых достижений

2. Сравнительная криптография

  • Протестируйте стойкость различных классических шифров
  • Постройте рейтинг шифров по сложности взлома
  • Исследуйте компромиссы между удобством и безопасностью

3. Современные приложения

  • Изучите применение частотного анализа в современных задачах:
    • Компрессия данных
    • Машинное обучение
    • Биоинформатика
    • Анализ социальных сетей

5.3 Научная работа: “Математические модели языка”

Углубленные исследования:

Теория информации в лингвистике:

H(X) = -Σ p(x) log₂ p(x)

где H(X) — энтропия языка, p(x) — вероятность символа x.

Задачи для исследования:

  1. Вычислите энтропию русского языка на уровне букв
  2. Сравните с энтропией других языков
  3. Исследуйте связь между энтропией и сложностью взлома шифров
  4. Разработайте модель “идеального” шифра с максимальной энтропией

🏆 ОЛИМПИАДНЫЕ ЗАДАЧИ

Задача №1: “Двойное шифрование” (Региональный уровень)

Сообщение было дважды зашифровано: сначала шифром Цезаря, затем шифром подстановки. В результате получился текст:

ЩМЗЖЗЖМЛТЗМЪЩЖЗЩЖТЗЗЩМЪЛЩМТЗЛЩМЪМЩЖМЪЛТЗМЪМТ

Известно, что в исходном сообщении была фраза “ИНФОРМАЦИОННАЯ БЕЗОПАСНОСТЬ”.

Задание: Найдите оба ключа и восстановите полное сообщение.

Подсказка: Используйте знание структуры известной фразы для определения паттернов.

Задача №2: “Неполный ключ” (Всероссийский уровень)

Перехвачено сообщение, зашифрованное шифром Виженера:

ЯЮНЩЖФЦОФЖЮУЗЖОГНЧЛФЦЩЧЖНЦТЛХЫНЦЖФЙЖОЧЪЖЦХН
ТЛФЙЧЛФЦЗЛЩКГНЧОЪЦХНФЙЧЖУЫЩКЖФЩЧЖФЙЖЪЮЖБХ

Разведка установила, что ключ начинается с “МАТЕМАТИКА”, но остальная часть неизвестна.

Задание:

  1. Определите полную длину ключа
  2. Восстановите недостающую часть ключа
  3. Расшифруйте сообщение

Задача №3: “Адаптивный шифр” (Международный уровень)

Создан модифицированный шифр Виженера, где ключ изменяется в процессе шифрования по правилу:

новый_ключ = f(старый_ключ, позиция_в_тексте)

Перехвачен фрагмент:

ЕЛЛПЦФЗЖЩУРЪОЪЛФЙЮШЭЬЙЯЧЁЦЩЖЗГЙЮЩШЖОЪТЦШЭЖ

Известно, что функция f представляет собой циклический сдвиг ключа на количество позиций, равное текущей позиции по модулю длины ключа.

Задание: Разработайте алгоритм взлома такого адаптивного шифра.


📝 КОНТРОЛЬНЫЕ ЗАДАНИЯ

Тест базового уровня

1. Какая буква наиболее часто встречается в русском языке?

  • А) А
  • Б) Е
  • В) О ✓
  • Г) И

2. Индекс совпадений для русского текста приблизительно равен:

  • А) 0.030
  • Б) 0.055 ✓
  • В) 0.067
  • Г) 0.100

3. Метод Касиски используется для:

  • А) Взлома шифра Цезаря
  • Б) Определения длины ключа Виженера ✓
  • В) Генерации случайных ключей
  • Г) Оценки стойкости шифра

Практические задания

Задание 1: Взломайте шифр Цезаря

ЖЕЧЕЫПЕ СЛШЕЧЛУЕ ТЕДУГЧМЧ

Задание 2: Определите длину ключа Виженера

МЮТЪЖЧНУСЛЧЖГЧНТЛФЩЖУРЪОХЭНУСЛБТЧЖГЧЖТЗЩБТЧЖ
ЖГЧЖТЗЧЖУРЪОЪЖЭНЦЮЛЦЖЧЖГЧЖТЗНЬЗЮЛЦЖЧЖГЧЖТЗ

Задание 3: Создайте программу для автоматического частотного анализа любого текста.


🎯 МЕТОДИЧЕСКИЕ РЕКОМЕНДАЦИИ ДЛЛ ПЕДАГОГОВ

Планирование уроков

Урок 1-2: Теоретические основы (2 часа)

  • История развития криптоанализа
  • Математические основы частотного анализа
  • Языковые закономерности
  • Демонстрация на простых примерах

Урок 3-4: Практический взлом (2 часа)

  • Взлом шифра Цезаря вручную
  • Использование программных инструментов
  • Анализ результатов и их интерпретация
  • Групповая работа над сложными примерами

Урок 5-6: Продвинутые методы (2 часа)

  • Метод Касиски для полиалфавитных шифров
  • Индекс совпадений и статистические тесты
  • Программирование алгоритмов взлома
  • Исследовательские проекты

Дифференцированный подход

Для сильных учащихся:

  • Самостоятельная разработка алгоритмов
  • Исследование современных приложений
  • Участие в криптографических олимпиадах
  • Изучение теории информации

Для средних учащихся:

  • Работа с готовыми программами
  • Анализ конкретных примеров
  • Групповые проекты
  • Создание презентаций

Для начинающих:

  • Визуальный анализ простых шифров
  • Использование онлайн-инструментов
  • Исторические экскурсы
  • Практические демонстрации

Междисциплинарные связи

Математика:

  • Теория вероятностей и статистика
  • Теория чисел
  • Дискретная математика
  • Алгебра

Информатика:

  • Алгоритмизация и программирование
  • Структуры данных
  • Сложность алгоритмов
  • Обработка текста

История:

  • История криптографии
  • Военная история
  • История науки
  • Развитие технологий

Русский язык:

  • Фонетика и морфология
  • Лексикология
  • Стилистика
  • Корпусная лингвистика

📚 ДОПОЛНИТЕЛЬНЫЕ МАТЕРИАЛЫ

Онлайн-ресурсы

Интерактивные инструменты:

  • CrypTool — образовательная программа по криптографии
  • Rumkin.com — онлайн инструменты для шифрования

Соревнования и олимпиады:

  • CryptoHack — современная криптографическая платформа
  • Всероссийская олимпиада школьников по информатике

Программное обеспечение

Python библиотеки:

pip install matplotlib numpy scipy cryptography

Специализированное ПО:

  • CrypTool (бесплатное обучающее ПО)
  • SageMath (математический пакет с криптографическими функциями)
  • Wolfram Mathematica (коммерческий пакет)

🔍 ЗАКЛЮЧЕНИЕ

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

  1. Развить аналитическое мышление через поиск закономерностей в данных
  2. Освоить статистические методы на интересном прикладном материале
  3. Понять связь между теорией и практикой в области информационной безопасности
  4. Приобрести навыки программирования для решения нестандартных задач