Skip to content

Latest commit

 

History

History
162 lines (113 loc) · 14.4 KB

README.md

File metadata and controls

162 lines (113 loc) · 14.4 KB

The-cryptographer-project

Development of a cryptographer based on the "Caesar Cipher" method.

Техническое задание

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

Основные задачи:

1. Реализация шифра Цезаря:

  • Создание и использование алфавита.
  • Алгоритм сдвига символов в соответствии с заданным ключом.

2. Обработка файлов:

  • Функциональность для работы с файлами (чтение, запись).
  • Обработка больших текстовых файлов.

3. Валидация входных данных:

  • Проверка существования файлов.
  • Допустимость ключей.

Режимы работы:

Шифрование текста:

  • Функция шифрования, принимающая файл, ключ и записывающая зашифрованный текст в новый файл.

Расшифровка текста:

  • Функция расшифровки с использованием известного ключа.

Расшифровка методом brute force (опционально):

  • Реализация метода 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.
Желательно этим заморочиться уже после создания основной программы. Однако если не успеваешь или не хочешь тратить на это время, можно создать простое текстовое меню и вывести его в консоль.


Работа с файлами

Для работы с файлами рекомендуется использовать библиотеку Java NIO, так как:

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

Расшифровка

Для нее нужно знать сдвиг (ключ) и алфавит.

Для каждого символа зашифрованного текста нужно:

  • проверить что он есть в твоем алфавите. Если нет — тебя ломают хакеры. Паникуй (ну, или верни ошибку).
  • найти его позицию в алфавите.
  • найти символ на позиции смещенной на заданный сдвиг (но только помни: ты не пытаешься еще раз зашифровать шифр, поэтому сдвигаем в другую сторону).
  • заменить зашифрованный символ на расшифрованный

Ты будешь использовать этот код использовать в следующих подзадачах, поэтому выводить результат можно в поток.
Сохранить результат нужно в файл.


Взлом (Brute Force)

Ты можешь использовать код который написал для расшифровки при известном ключе, подставляя все возможные значения ключа.

Но как понять получилось ли расшифровать?
Используй пример текста (репрезентативный текст автора или в том же стиле). Можно составить словарь слов и составить метрику основанную на том, сколько слов совпало и какой они длины; или иную метрику которая изучает длину слов и предложений, или посмотреть какие буквы чаще всего предшествуют каким буквам или словарь наиболее частых начал слова (3 буквы), можно вообще не использовать никаких репрезентативных файлов и проверить правильность пунктуации и пробелов; Вариант с наилучшими результатами сохрани в файл вывода.


Взлом (Статистический анализ)

Дополнительное требования(опционально)

Используй пример текста (репрезентативный текст автора или в том же стиле) и составь статистику букв (например, как часто встречается на каждые 1000 символов). Кстати. Легко взломать шифр и без такого файла и анализа: попробуйте угадать пробел — это наверняка наиболее часто встречающийся символ в обычном тексте.

Далее составь такую же статистику для зашифрованного текста. Учти, просто считать символы не достаточно так как тексты могут быть разной длины!

Далее посчитай отклонение для каждого возможного сдвига зашифрованной статистики относительно репрезентативной (можно для этого использовать сумму квадратов отклонения или дот-произведение векторов). Найди сдвиг, дающий минимальное отклонение и расшифруйте используя этот сдвиг.