Кодировки и шифрование¶
Кодировка — это правила перевода одного набора символов в другой. В отношении компьютерных программ речь идёт о правилах кодирования последовательности из нулей и единиц в текст, число или что-либо другое.
Наиболее распространённые кодировки
Латинские буквы, цифры и простые символы
Кириллическая кодировка (русский и другие языки)
Кодировка для русского языка
Юникод-кодировка, все языки (длина символа — 8 бит)
Юникод-кодировка, все языки (длина символа — 16 бит)
Unicode — стандарт кодирования символов, включающий в себя знаки почти всех письменных языков мира. В настоящее время стандарт является преобладающим в Интернете.
- стандарт включает более 138 тысяч символов;
- каждый символ имеет определённое название и код (номер);
- коды состоят из латинских букв и шестнадцатеричных цифр, например: U+0073 .
Примеры кодов, имен и соответствующих символов:
Конвертация данных между байтам и строками¶
Данные по сети передаются, как правило, в байтах. Например, метод socket.recv() получает данные в байтах. Чтобы преобразовывать данные из байт в строки и наоборот используются специальные методы:
- метод encode(‘encoding_name’) — позволяет перевести данные из строки в байты (str -> bytes);
- метод decode(‘encoding_name’) — позволяет перевести данные из байт в строку (bytes -> str);
В коде будет выглядеть так:
# кодирование строки в байты s = 'привет' s_bytes = s.encode ('utf-8') print (s_bytes) Out: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' # декодирование байт в строку s_dec = s_bytes.decode ('utf-8') print (s_dec) Out: привет
При работе с кодировкой важно помнить:
- Если вы кодируете строку в байты кодировкой UTF-8, то и перекодировать её из байт нужно этой же кодировкой. Некоторые кодировки совместимы, но в большинстве случаев, нарушения этого правила ведёт к потере данных.
- В своём коде всегда используйте кодировки Unicode, оптимально UTF-8, она используется по умолчанию в большинстве методов и функций, так что это снижает риск ошибок.
- Декодирование байтовых данных в строки лучше производить сразу после их получения, а кодирование в байты — только перед отправкой. В коде лучше работать с привычными типами данных (строки, списки, числа), не с байтами, ведь большинство методов в Python с байтовыми строками не работают (или работают не так, как можно ожидать).
Шифрование¶
Шифр Цезаря
Шифр Цезаря — это вид шифра подстановки, в котором каждый символ в открытом тексте заменяется символом, находящимся на некотором постоянном числе позиций левее или правее него в алфавите. Например, в шифре со сдвигом вправо на 3, A была бы заменена на D, B станет E, и так далее.
Формула для кодирования символа:
symbol_encoded = ((((symbol) - first + key) % size) + first)
Алфавит случайным образом записывают в 2 строки, и шифрование текста происходит заменой буквы на соседнюю ей по вертикали. Например:
['v', 'q', 'f', 's', 'p', 'u', 'n', 'a', 'm', 'j', 'c', 'k', 'h'] ['l', 'r', 'o', 'e', 'x', 'd', 'z', 'g', 'b', 'w', 't', 'i', 'y'] In: hello Out: ysvvf
Шифр Виженера
На алфавите длиной N вводят операцию добавления (циклического сдвига) букв. Пронумеровав буквы, добавляем их по модулю N (для англ. алфавита N=26).
Выбираем слово-ключ (пускай pass) и подписываем его под сообщением сколько нужно раз:
Сообщение: search Ключ: passpa Шифр: hesjrh
Задания¶
- Доработайте прототип чата из прошлого урока таким образом, чтобы он корректно работал с русским языком (используйте методы кодирования и декодирования байтовых строк).
2. Напишите функцию для шифрования файла шифром Цезаря. Расшифруйте:
key = 2 s = 'Oquv uvctu ctg qdugtxgf vq dg ogodgtu qh dkpctb uvct ubuvgou'
3. Напишите функцию для шифрования файла шифром пар. Расшифруйте:
d_1 = [109, 122, 106, 115, 100, 99, 105, 120, 110, 98, 121, 118, 107] d_2 = [112, 103, 108, 104, 111, 102, 119, 117, 97, 101, 116, 113, 114] s = 'A hynk wh na nhykdadpwfnj delbfy fdahwhywaz dc n jxpwadxh hmsbkdwo dc mjnhpn sbjo ydzbysbk et wyh dia zknqwyt.'
4.* Напишите функцию для шифрования файла шифром Виженера. Расшифруйте. 5. Добавьте в чат (с кодировкой) возможность выполнять шифрование и дешифрование сообщения одним из шифров по выбору пользователя. 6. Доработайте чат таким образом, чтобы пользователь отправлял серверу имя зашифрованного файла и шифр, а сервер дешифровал его и отправлял содержимое файла обратно пользователю.
Полезные ссылки¶
Русский алфавит через char
Русский алфавит
Нужно создать программу так чтобы переводила каждую букву Русского алфавита в цифру + 2 А 1+2=.
Русский алфавит в массив
Как бы так задать массив русского алфавита, но не вручную вводить каждую букву.
Строки, русский алфавит
Задание: Дана последовательность слов русского языка, между словами – запятая, за последним словом.
Строки и русский алфавит
удалите это, пожалуйста Случайно не в тот раздел написал. Извините
Сообщение было отмечено Rottbauer как решение
Решение
Добавлено через 3 минуты
Логично, что как-то так. Только учитывайте, что кодировка у «Ё» не соответствует правилу.
Строки и русский алфавит
В проге считываешь с файла строку на кириллице. Например: "ололо", длину выведет 10. Почему? А как.
Множества. Русский алфавит
Здравствуйте. Дан текст на русском языке. Напечатать в алфавитном порядке все согласные буквы.
AnsiString и русский алфавит
Здравствуйте, возник вопрос по AnsiString такого рода : дана строка AnsiString, как получить.
Множества. Русский алфавит
дан текст на русском языке. Напечатать в алфавитном порядке все звонкие согласные буквы, которые.
Вывести русский алфавит
Вывожу английский алфавит через Chr(i+97) без проблем, а вот русский не получается i+224. Что не.
Вывести в консоли русский алфавит
программа должна вывести в консоли русский алфавит, после чего если нажать цифру 1, то выскочит.
Кирилица в Python
Есть ли в python аналог для string.ascii_letters , только для кириллицы?
>>> import string >>> string.ascii_letters 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' >>>
Ответы (3 шт):
Не думаю, что для кириллицы это есть.
vowels = 'аоиеёэыуюя' consonants = 'бвгджзйклмнпрстфхцчшщьъ' cyrillic_lower_letters = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя' cyrillic_upper_letters = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ' cyrillic_letters = cyrillic_lower_letters + cyrillic_upper_letters
Зная, что код кириллических символов в таблице unicode идёт от 1040 до 1103, где сначала заглавные, а затем строчные, мы можем сделать так:
cyrillic_lower = [(lambda c: chr(c))(i) for i in range(1072, 1104)] cyrillic_upper = [(lambda c: chr(c))(i) for i in range(1040, 1072)] cyrillic_ansi = cyrillic_lower + cyrillic_upper
И получим следующий список: [‘а’, ‘б’, ‘в’, ‘г’, ‘д’, ‘е’, ‘ж’, ‘з’, ‘и’, ‘й’, ‘к’, ‘л’, ‘м’, ‘н’, ‘о’, ‘п’, ‘р’, ‘с’, ‘т’, ‘у’, ‘ф’, ‘х’, ‘ц’, ‘ч’, ‘ш’, ‘щ’, ‘ъ’, ‘ы’, ‘ь’, ‘э’, ‘ю’, ‘я’, ‘А’, ‘Б’, ‘В’, ‘Г’, ‘Д’, ‘Е’, ‘Ж’, ‘З’, ‘И’, ‘Й’, ‘К’, ‘Л’, ‘М’, ‘Н’, ‘О’, ‘П’, ‘Р’, ‘С’, ‘Т’, ‘У’, ‘Ф’, ‘Х’, ‘Ц’, ‘Ч’, ‘Ш’, ‘Щ’, ‘Ъ’, ‘Ы’, ‘Ь’, ‘Э’, ‘Ю’, ‘Я’]
Если нужно получить именно строку, то вот:
cyrillic_ansi_str = ''.join(cyrillic_ansi)
и соответствующий результат: ‘абвгдежзийклмнопрстуфхцчшщъыьэюяАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ’
Ну тогда и я свой вариант добавлю, если порядок следования букв не очень важен:
cyrillic_letters = ''.join(map(chr, range(ord('А'), ord('я')+1))) + 'Ёё' # 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяЁё'
Будет работать в любой кодировке, где русские буквы идут в таблице подряд, начиная с А и заканчивая я . Правда, с Ёё отдельный прикол, но они обычно везде как-то отдельно лежат.