Практика 4
Задания в классе
Шифр Виженера
статья в википедии
Шифр Виженера - это метод полиалфавитного шифрования буквенного текста с использованием ключевого слова. По сути это метод простой многоалфавитной замены.
В шифре Цезаря каждая буква алфавита сдвигается на несколько позиций; например в шифре Цезаря при сдвиге +3, A стало бы D, B стало бы E и так далее. Шифр Виженера состоит из последовательности нескольких шифров Цезаря с различными значениями сдвига. На каждом этапе шифрования используются различные алфавиты, выбираемые в зависимости от символа ключевого слова.
Например:
сообщение: my secret code i want to secure
ключ: pa ssword myse c retc od eiwant
Где password
- это пароль. Так как ключ должен быть одинаковой длины,
что и сообщение, поэтому пароль дополняется до соответствующей длины
с помощью самого же сообщения.
Для расшифрования необходимо потоково расшифровывать сообщение и добавлять
расшифрованные символы в генерируемый на лету ключ.
Функция шифрования: , где n
- это мощность алфавита, например 26 для английского. - это j-ая
буква открытого текста, а - это j-ый символ ключа.
Функция расшифрования: .
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 ночи, так что прошу прощения за баги или неточности.
Домашнее задание
Программирование
Дополнить программу так, чтобы она могла читать данные из файла. Будьте внимательны, файл может быть больше, чем оперативной памяти на вашем компьютере.
Описание условий:
- Пользователь зашел в папку c двумя файлами:
cipher.py
иdecipher.py
. - На диске где-то существует большой текстовый файл:
/home/student/big_file.txt
.
Описание пользовательской истории:
-
Пользоатель запускает из терминала программу:
python3 cipher.py /home/student/big_file.txt /home/student/ciphered_file.txt password
, тем самым получая зашифрованный файл. -
Пользователь запускает из терминала
python3 decipher.py /home/student/ciphered_file.txt /home/student/open_text.txt password
, тем самым получая расшифрованный файл. -
В случае ошибок нужно выводить в консоль понятное сообщение об ошибке. Сообщения должны быть на английском языке.
Hints
Вам может понадобиться функция open для чтения файлов.
Вам может понадобиться пакет sys для чтения аргументов командной строки. Это может выглядеть следующим образом:
import sys
def main(argv):
print(argv)
if __name__ == '__main__':
main(sys.argv)
Чтение
- Глава 10 “Функции” (стр. 59 по 69) из книги A Byte of Python. Будет тест!!!