Рассмотрим обратный квадрат Виженера, то есть таблицу, которая сопоставляет паре (символ зашифрованного текста; символ ключевого слова) символ исходного текста. Договоримся называть дистанцией между двумя символами разность их позиций в алфавите: например, дистанция между 'а' и 'в' — это 2. Тогда можно заметить, что если дистанция между i- м и j- м символами ключевого слова равна d, то дистанция между соответствующими символами исходного текста составляет - d. Следовательно, если нам удастся найти ключевое слово, то мы сможем свести шифр Виженера к шифру простой замены: каждая буква исходного текста будет заменена на другую, при этом соответствие букв будет взаимно- однозначным.
Взломать такой шифр не составит труда. Остается найти ключевое слово. Пусть нам известно, что длина ключевого слова — L символов. Тогда текст можно разбить на L групп, каждая из которых будет зашифрована с помощью одного символа ключевого слова, т. При этом используемые перестановки алфавита будут отличаться лишь сдвигом, равным с точностью до знака дистанции между соответствующими символами ключевого слова.
Используя методы частотного криптоанализа, мы сможем определить эти сдвиги. Таким образом, программа будет состоять из трех частей: 1) Определение длины ключевого слова. Поиск ключевого слова. Поиск перестановки алфавита и расшифровка текста. Длина ключевого слова. Длину ключевого слова проще всего найти, используя метод индекса совпадений.
Этот метод был предложен Уильямом Фридманом в 1. Виженера, но он сработает и в нашем случае. Метод основан на том факте, что вероятность совпадения двух случайных букв в некотором достаточно длинном тексте (индекс совпадений) — это постоянная величина. Таким образом, если разбить текст на L групп символов, каждая из которых зашифрована шифром простой замены (напомню, это и означает, что L — длина ключевого слова), то индексы совпадений для каждой из групп будут довольно близки к теоретическому значению этой величины; для всех других разбиений индексы совпадений будут гораздо ниже. Индекс совпадений можно посчитать по формуле(fi — количество i- х букв алфавита в тексте, а n — его длина)Ниже, например, приведены индексы совпадений для текста, зашифрованного с помощью ключа «проект» (6 символов). Таким образом, для определения длины ключевого слова нужно посчитать индексы совпадений для разбиения текста на L = 1, 2.
Что если текст зашифрован с использованием ключа, который можно разделить на несколько похожих частей? Снизу приведена таблица индексов совпадений для того же текста, что и в первом примере, но зашифрованного с помощью ключа «космос» (те же 6 символов).
Как же определить длину ключа в таком случае? Я поиграл с различными способами и выяснил, что проще всего выбрать необходимый индекс так: нужно взять первый индекс, для которого справедливо: 1.
ИС > ИСi, i = 1, 2. Более того, если текст зашифрован с помощью слова, состоящего из одинаковых частей (например, «тартар»), то длина ключевого слова в любом случае будет определена неверно (если, конечно, мы хотим найти осмысленное ключевое слово): нет никакой разницы между шифрованием ключом «тартар» и «тар». Поэтому важно дать пользователю возможность изменять длину ключа в ходе работы программы: к примеру, не подошла 6, значит, стоит попробовать 3 или 1. К счастью, для зашифрованной записки из книги все определяется довольно просто. Взглянув на таблицу индексов совпадений, можно с уверенностью сказать, что длина ключевого слова — 7 символов. Ключевое слово. Теперь, когда длина ключа найдена, можно приступить к поиску самого ключевого слова.
Сперва нужно определить вероятности различных сдвигов между группами, на которые мы разбили шифр (напомню, что каждая группа зашифрована с помощью некоторой перестановки алфавита, при этом перестановки отличаются лишь сдвигом каждой буквы на несколько позиций в алфавите). Для нахождения вероятностей сдвигов я воспользовался идеей, предложенной переводчиками «Этюдов». Если опустить все математические выкладки, она заключается в следующем. Для каждой группы мы считаем количество символов x (x = 'а', 'б', .., 'я') в ней и на основании информации о частоте букв в русском языке оцениваем вероятность того, что символу x шифра соответствует символ y (y = 'а', 'б', .., 'я') исходного текста. Сопоставляя полученные таблицы вероятностей для различных групп, мы можем вычислить вероятности сдвигов r (r = 1, 2, .., 3. В результате мы получаем таблицу, показывающую, какова вероятность сдвига r между группами i и j для любых двух групп и любого сдвига.
Найти само ключевое слово можно двумя способами. Первый способ — это найти наилучшую конфигурацию сдвигов, используя (только) полученную таблицу.
Полный перебор занял бы очень много времени, поэтому я пошел другим путем. Я искал ключ следующим образом.
Возьмем любое слово подходящей длины и вычислим его характеристику — сумму вероятностей сдвигов между каждыми двумя символами в нем (сдвиги между символами ключевого слова и между буквами перестановок в различных группах шифра совпадают с точностью до знака). Теперь внесем небольшое изменение в исследуемое слово. Если после изменения характеристика слова стала лучше, то мы запоминаем новое слово, в противном же случае забываем новое слово и возвращаемся к старому. Внося таким образом случайные изменения, мы довольно быстро найдем лучшее слово. Проблема заключается лишь в том, что наилучшее слово далеко не всегда является ключевым. Тесты показали, что уже для текстов из 1. Например, лучшее слово для записки из книги — «федиска».
Не знаю я такого слова! Для более коротких текстов ключ определяется совершенно неверно. Поэтому от поиска ключа на основании только таблицы пришлось отказаться. Лекции По Математике Спо. Второй способ поиска ключа простой и неинтересный, зато эффективный.
Мы берем словарь и вычисляем характеристику каждого подходящего слова (для повышения скорости работы программы я разделил слова по их длинам). Лучшее слово мы берем в качестве ключевого. Такой метод работает корректно даже для коротких (4.