Pascal ABC

 

ГЛАВНАЯ
ССЫЛКИ
ОЛИМПИАДНЫЕ ЗАДАНИЯ
Очень простые

Проблема с A и B

Трамвайные билеты

Шифр Цезаря

Четные и нечетные члены последовательности

"Мы вас упакуем!"

Простые

Равновеликие прямоугольники

Скобки

 

Уравнение

 

Вирусы

 

КВН

 

Коррекция кода

 

Степень

 

Демократия в опасности

 

Пуговицы

 

A to B

 

Палиндромы

 

Почти Крэг Туми

 

Виза

 

Ездец

 
Средней сложности  

MIME64

 

Куль хацкеры

 

Редкое имя

 

Города

 

Исправления

 

Банки

 

2^n

 

Ниточка

 

Массивище

 

Знакомые

 

Считаем кораблики

Лошадью ходи!

Левые повороты

Прицельное метание помидор

Анаграммы

Треугольник

Принцип компании

Уникальная строка

Конфуз

K-ичные числа

Михаил Густокашин против бюрократии

Агенты

Игра в слова

Сложные

Диски

Домино

Монеты

Программистика

Хитрющая строка

Робот-сапер

Квадраты

Упаковка простых

Оппозиция

 

Замок

 

Многоугольники

 

Электронные часы

 

Дождик

 

Черепаха

 

Метро

 

Террористы

 

Школы

 
Очень сложные/особо интересные  

Система Защиты

 

Бизнес-классики

 

Телеметрия

 

Лесной пожар

 

Олимпиада

 

Автобусный диспетчер

 

 Кубики

 

Электронная почта

 

Автобус

 

 

 

 

ОЛИМПИАДНЫЕ ЗАДАНИЯ

Олимпиадные задачи с рекомендациями к решениям

Задача 21: Куль хацкеры.

Расшифровать файл, зашифрованный шифром Цезаря, не имея ключа. Шифруются только большие русские буквы.

Решение:
Вспомнили задачу 3?
Теперь мы попытаемся сделать расшифровку не имея ключа. Для этого нам придется немного коснуться основ криптографии. Каждый текст имеет свою специфику - некоторые символы встречаются в нем часто, другие реже, но в среднем частота символов примерно одинакова. Этим мы можем воспользоваться в нашем нелегком труде - написании взламывающей программы.
Для начала нам понадобиться таблица-эталон с частотой встречи букв в стандартном русском тексте. Она выглядит примерно так:

А := 0.074438;
Б := 0.016189;
В := 0.050396;
Г := 0.019352;
Д := 0.028179;
Е := 0.089613;
Ж := 0.010010;
З := 0.016637;
И := 0.074109;
Й := 0.014743;
К := 0.032171;
Л := 0.037507;
М := 0.031160;
Н := 0.067640;
О := 0.113329;
П := 0.026275;
Р := 0.049378;
С := 0.056569;
Т := 0.063209;
У := 0.023785;
Ф := 0.001466;
Х := 0.009276;
Ц := 0.004299;
Ч := 0.014236;
Ш := 0.006525;
Щ := 0.004035;
Ъ := 0.000240;
Ы := 0.017820;
Ь := 0.016222;
Э := 0.004256;
Ю := 0.007210;
Я := 0.019724;

Уфф... Сгенерировать эту таблицу - иногда тоже проблема.
А теперь собственно к задаче. Мы имеем две таблицы - таблицу-эталон и таблицу для взламываемого файла. как же определить какой сдвиг был использован.
Первая моя реализация (которую я придумал сам) была туповатой и работала только на больших файлах. Она выбирала самую часто встречающуюся букву и считала ее буквой "О". Исходя из этого производилась расшифровка. Однако, в некоторых текстах самая частая - вовсе не буква "О" и, следовательно, программа работала неверно.
Следующая реализация вплотную пододвинула меня к истине(она вполне рабочая, но есть вариант чуть-чуть лучше, но о нем позже):
Я производил циклический сдвиг таблицы для взламываемого файла и считал сумму модулей разницы частот появления символов в таблице-эталоне и передвинутой таблицы. Например:

Пусть алфавит состоит из трех букв: {А, Б, В} с частотами:
А := 0.1;
Б := 0.3;
В := 0.6;

На вход мы получаем сообщение состоящее из того же алфавита, но с частотами:
А := 0.35;
Б := 0.55;
В := 0.1;

Теперь посчитаем нашу хитрую функцию для всех возможных сдвигов: {0, 1, 2}
[0] := |0.1 - 0.35| + |0.3 - 0.55| + |0.6 - 0.1| = 1; - очень скверно
[1] := |0.1 - 0.55| + |0.3 - 0.1| + |0.6 - 0.35| = 0.9; - скверно
[2] := |0.1 - 0.1| + |0.3 - 0.35| + |0.6 - 0.55| = 0.1; - скверно, но верно

Минимальная сумма получилась для сдвига 2, следовательно он и является ключом!
Другой способ решения состоит в том чтобы считать не сумму модулей, а сумму квадратов (он несколько более правильный, т.к. мелкие погрешности в нем почти исчезают), но и мой алгоритм расшифровывает практически все.
Пожалуй, в следующий раз надо сломать RSA-алгоритм ;)

ДОПОЛНЕНИЕ ОТ 18.02.02:
Недавно узнал еще один способ решения этой задачи, заключающийся в оценивании редко и часто встречающихся сочетаний букв. Например: четыре согласные подряд - плохое сочетание, а окончание "-ий", "-ой" или "-ый" - хорошее. Для каждого сдвига считается разность хороших и плохих сочетаний - в каком сдвиге эта разность наибольшая - тот и лучший.

Далее ð





 


 

 

 
 

СЕРВИС

Copyright © 2008 СОШ №2 им. Н.П. Массонова г.Свислочь © Синица А.А.