Задания в классе

Шифр Виженера

статья в википедии

Шифр Виженера - это метод полиалфавитного шифрования буквенного текста с использованием ключевого слова. По сути это метод простой многоалфавитной замены.

В шифре Цезаря каждая буква алфавита сдвигается на несколько позиций; например в шифре Цезаря при сдвиге +3, "A" стало бы "D", "B" стало бы "E" и так далее. Шифр Виженера состоит из последовательности нескольких шифров Цезаря с различными значениями сдвига. На каждом этапе шифрования используются различные алфавиты, выбираемые в зависимости от символа ключевого слова.

Например:

сообщение: my secret code i want to secure
ключ:      pa ssword myse c retc od eiwant

Где password - это пароль. Так как ключ должен быть одинаковой длины, что и сообщение, поэтому пароль дополняется до соответствующей длины с помощью самого же сообщения.

Для расшифрования необходимо потоково расшифровывать сообщение и добавлять расшифрованные символы в генерируемый на лету ключ.

Функция шифрования: $c_j = m_j + k_j (mod n)$, где $n$ - это мощность алфавита, например 26 для английского. $m_j$ - это $j$-ая буква открытого текста, а $k_j$ - это $j$-ый символ ключа.

Функция расшифрования: $m_j = c_j - k_j (mod n)$.

Hints

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

Тесты

def encrypt(open_text, password, alphabet='abcdefghijklmnopqrstuvwxyz'):
    return open_text

def decrypt(ciphered_text, password, alphabet='abcdefghijklmnopqrstuvwxyz'):
    retrun ciphered_text

class TestVigener(unittest.TestCase):
    def test_empty():
        text = ''
        pwd = ''
        self.assertEqual(decrypt(encrypt(text, pwd)), text)

    def test_one():
        text = 'codewars'
        pwd = 'password'
        cipher = 'rovwsoiv'
        self.assertEqual(encrypt(text, pwd), cipher)

    def test_two():
        text = 'waffles'
        pwd = 'password'
        cipher = 'laxxhsj'
        self.assertEqual(decrypt(cipher, pwd), text)

    def text_third():
        text = 'amazingly few discotheques provide jukeboxes'
        pwd = 'password'
        cipher = 'pmsrebxoy rev lvynmylatcwu dkvzyxi bjbswwaib'
        self.assertEqual(decrypt(cipher, pwd), text)
        self.assertEqual(encrypt(text, pwd), cipher)

if __name__ == '__main__':
    unittest.main()

Короче я это писал в поезде в 12 ночи, так что прошу прощения за баги или неточности.

Домашнее задание

Программирование

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

Описание условий: