Страницы

Поиск по вопросам

пятница, 2 ноября 2018 г.

Какие преобразования кодировки произошли со строкой?

Жила была utf-8 строка: Съешь ещё этих мягких французских булок, да выпей же чаю
Строка пустилась в какие-то приключения скорее связанные с преобразованием кодировки, в результате превратилась в следующую:
Ñúåøü åù¸ ýòèõ ìÿãêèõ ôðàíöóçñêèõ áóëîê, äà âûïåé æå ÷àþ
Внимание вопрос: что с ней происходило?
Я разумеется попробовал определить это с помощью Лебедевского декодера и пары аналогичных инструментов, но по-быстрому ничего вразумительного не получил.
В общем иероглифы ужасно знакомые, поэтому надеюсь что кто-то их здесь узнает)


Ответ

Работает вот такая цепочка преобразований:
>>> 'Ñúåøü ГҐГ№Вё ГЅГІГЁГµ ìÿãêèõ ôðà íöóçñêèõ áóëîê, äà âûïåé æå Г·Г Гѕ' \ .encode('cp1251') \ .decode('utf-8', errors='ignore') \ .encode('cp1252') \ .decode('cp1251') 'Съешь ещё этих мягких фр нцузских булок, д выпей же ч ю'
Посмотрим что случилось с буквой а
>>> 'а'.encode('cp1251').decode('cp1252').encode('utf-8').decode('cp1251') 'Г\xa0'
видимо "Г\xa0" при копировании превратилось в "Г "

Как догадаться:
Есть строка "Ñúåøü ГҐГ№Вё", надо преобразовать ее в байты. Г и Ё - это кириллические буквы, значит их можно преобразовать кириллической кодировкой, 1251 или 866:
>>> 'Ñúåøü åù¸'.encode('cp866') Traceback (most recent call last): File "", line 1, in 'Ñúåøü åù¸'.encode('cp866') File "C:\Python36\lib\encodings\cp866.py", line 12, in encode return codecs.charmap_encode(input,errors,encoding_map) UnicodeEncodeError: 'charmap' codec can't encode character '\u2018' in position 1: character maps to >>> 'Ñúåøü åù¸'.encode('cp1251') b'\xc3\x91\xc3\xba\xc3\xa5\xc3\xb8\xc3\xbc \xc3\xa5\xc3\xb9\xc2\xb8'
"\xc3\xbc \xc3\xa5" - это кодировка UTF-8, один байт на пробел, два байта на букву.
>>> b'\xc3\x91\xc3\xba\xc3\xa5\xc3\xb8\xc3\xbc \xc3\xa5\xc3\xb9\xc2\xb8'.decode('utf-8') 'Ñúåøü åù¸'
Опять, есть строка, надо сделать ее байтами. Русских букв тут нет, зато есть "латинские международные", пробуем кодировку 1252:
>>> 'Ñúåøü åù¸'.encode('cp1252') b'\xd1\xfa\xe5\xf8\xfc \xe5\xf9\xb8'
Получились байты в однобайтовой кодировке. Опять пробуем 1251 и 866:
>>> b'\xd1\xfa\xe5\xf8\xfc \xe5\xf9\xb8'.decode('cp866') '╤·х°№ х∙╕' >>> b'\xd1\xfa\xe5\xf8\xfc \xe5\xf9\xb8'.decode('cp1251') 'Съешь ещё'

Выше использовался Python3. Также подойдет любой другой язык или утилита которая умеет преобразовывать текст в байты и обратно.

Комментариев нет:

Отправить комментарий