Development of a cryptographer based on the "Caesar Cipher" method.
Разработать программу, позволяющую шифровать и расшифровывать текст с использованием шифра Цезаря. Программа должна поддерживать несколько режимов работы, обеспечивать обработку больших файлов и иметь валидацию входных данных. Опционально можно добавить графический интерфейс пользователя, а также статистический анализ для автоматического взлома шифра.
- Создание и использование алфавита.
- Алгоритм сдвига символов в соответствии с заданным ключом.
- Функциональность для работы с файлами (чтение, запись).
- Обработка больших текстовых файлов.
- Проверка существования файлов.
- Допустимость ключей.
- Функция шифрования, принимающая файл, ключ и записывающая зашифрованный текст в новый файл.
- Функция расшифровки с использованием известного ключа.
- Реализация метода
brute force
для перебора всех ключей до успешного расшифрования.
- Разработка алгоритма статистического анализа для автоматической расшифровки без ключа, используя особенности языка.
- Текстовое меню или (опционально) графический интерфейс
- Обработка ошибок и исключений.
- Оптимизация для производительности.
- Документация и тестирование.
программа работает в нескольких режимах
- Расшифровка текста с помощью ключа
- Расшифровка текста с помощью brute force (перебор всех вариантов)
- (дополнительно) Расшифровка с помощью статистического анализа текста
Программа должна открывать указанный пользователем файл с текстом и проделывать с ним одно из указанных выше действий. После этого создавать новый файл с результатом.
- Шифровка текста из заданного файла. На вход она получает адрес файла с оригинальным текстом, адрес файла в который нужно записать зашифрованный текст, и сдвиг по алфавиту (это является ключом шифра Цезаря).
Не забудь проделать проверку того что:- файл оригинала по заданному адресу существует
- ключ от 0 и до (размер алфавита - 1) (или можете взять остаток от деления на размер алфавита).
- Расшифровка при известном ключе. На входе — адрес зашифрованного файла и адрес куда писать расшифрованный файл, а также сдвиг по алфавиту который использовался при шифровании (ключ).
- Расшифровка методом
brute force
(перебором всех возможных сдвигов); На входе - адрес зашифрованного файла, (опционально) адрес файла с текстом который является примером текста что был зашифрован (например другой труд того же автора) и адрес файла который должен содержать расшифрованный текст. - Расшифровка методом статистического анализа; На входе тоже самое что и для расшифровке перебором.
Не забудь проделать валидацию входных данных.
Исходный текст для шифрования должен быть в файле. Желательно в формате .txt
. Программа должна уметь работать с большими текстами на сотни страниц. Этот файл программа должна уметь зашифровать и записать зашифрованный текст в другой файл.
Создай алфавит, в котором существует задача. По условию это русский алфавит и пунктуация . , ” ’ : - ! ? ПРОБЕЛ
Не забываем про пробел!
Как это можно сделать? Например, можно загнать алфавит в String
, несколько строк или массив String
.
Или… можно создать алфавит на основе множества Set
, массива или списка List
. А ещё можно воспользоваться таблицей ASCII
.
Помни, что алфавит не меняется, поэтому такую переменную логично сделать константой public static final
. Имя таких переменных принято писать заглавными буквами.
private static final List ALPHABET = Arrays.asList('а', 'б', 'в','г', 'д', 'е', 'ж', 'з', 'и',
'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т',
'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы',
'ь', 'э', 'я', '.', ',', '«', '»',':', '!', '?', ' ');
Или можно применить обычный массив (так как алфавит не меняется, нет никакого смысла засовывать его в список).
Массивы занимают меньше памяти, и поэтому, по возможности, надо использовать именно массивы, особенно если речь идет о примитивных типах (в списках примитивные типа оборачиваются в объекты и занимают значительно больше памяти).
private static final char[] ALPHABET = {'а', 'б', 'в', 'г', 'д', 'е', 'ж', 'з',
'и','к', 'л', 'м', 'н', 'о', 'п', 'р',
'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш',
'щ', 'ъ', 'ы', 'ь', 'э', 'я', '.', ',',
'«', '»', '"', '\'', ':', '!', '?', ' '};
Для нее нужно знать сдвиг (ключ) и алфавит.
- проверить что он есть в вашем алфавите. Если его нет, пропускаем этот символ.
- найти его позицию в алфавите. Подумай, какую структуру данных нужно использовать чтобы ускорить этот процесс (раз в 15), ведь необязательно же сканировать всю библиотеку в поисках книги на букву Ы (Ладно, П).
- найти символ на позиции смещенной на заданный сдвиг. Как это гарантировать? (можно сделать
_(позиция буквы + сдвиг) %( размер алфавита)_
. - заменить оригинальный символ на зашифрованный
Сохранить результат в файл (чтобы избежать плохого пользователя который попробует зафигачить тебе .bash_profile
или hosts
валидируй имя файла вывода!)
Графический интерфейс можно создать с помощью JavaFX
или Swing
.
Желательно этим заморочиться уже после создания основной программы. Однако если не успеваешь или не хочешь тратить на это время, можно создать простое текстовое меню и вывести его в консоль.
- Это более современный и производительный API по сравнению с IO.
- Поддерживает асинхронную обработку файлов.
- Обеспечивает корректную работу с большими файлами.
Для нее нужно знать сдвиг (ключ) и алфавит.
- проверить что он есть в твоем алфавите. Если нет — тебя ломают хакеры. Паникуй (ну, или верни ошибку).
- найти его позицию в алфавите.
- найти символ на позиции смещенной на заданный сдвиг (но только помни: ты не пытаешься еще раз зашифровать шифр, поэтому сдвигаем в другую сторону).
- заменить зашифрованный символ на расшифрованный
Ты будешь использовать этот код использовать в следующих подзадачах, поэтому выводить результат можно в поток.
Сохранить результат нужно в файл.
Ты можешь использовать код который написал для расшифровки при известном ключе, подставляя все возможные значения ключа.
Но как понять получилось ли расшифровать?
Используй пример текста (репрезентативный текст автора или в том же стиле). Можно составить словарь слов и составить метрику основанную на том, сколько слов совпало и какой они длины; или иную метрику которая изучает длину слов и предложений, или посмотреть какие буквы чаще всего предшествуют каким буквам или словарь наиболее частых начал слова (3 буквы), можно вообще не использовать никаких репрезентативных файлов и проверить правильность пунктуации и пробелов; Вариант с наилучшими результатами сохрани в файл вывода.
Дополнительное требования(опционально)
Используй пример текста (репрезентативный текст автора или в том же стиле) и составь статистику букв (например, как часто встречается на каждые 1000 символов). Кстати. Легко взломать шифр и без такого файла и анализа: попробуйте угадать пробел — это наверняка наиболее часто встречающийся символ в обычном тексте.
Далее составь такую же статистику для зашифрованного текста. Учти, просто считать символы не достаточно так как тексты могут быть разной длины!
Далее посчитай отклонение для каждого возможного сдвига зашифрованной статистики относительно репрезентативной (можно для этого использовать сумму квадратов отклонения или дот-произведение векторов). Найди сдвиг, дающий минимальное отклонение и расшифруйте используя этот сдвиг.