2015-11-18 2 views
0

В настоящее время я работаю над программой шифрования/дешифрования в python 3 и отлично работает со строками; однако у меня возникают проблемы с преобразованием его в байтовые строки, как в UTF-8, символ может быть выражен в любом месте от 1 до 4 байтов.Кодирование с фиксированной длиной в Python 3

>>>'\u0123'.encode('utf-8') 
b'\xc4\xa3' 
>>>'\uffff'.encode('utf-8') 
b'\xef\xbf\xbf' 

После некоторых исследований я обнаружил, что в настоящее время нет кодирования в Python 3, который имеет фиксированную длину для каждого байта и имеет все символы в кодировке UTF-8 - есть ли модуль/функция, что я могу использовать, чтобы обойти эту проблему (например, добавив пустые байты, чтобы каждый чарт кодировал байтовую строку длиной 4)?

+0

Вы имеете UTF-16, он кодирует в '2 * LEN (текст) + 2' байт. –

+0

UTF-8 - кодирование переменной длины. Таким образом, нет, нет кодировки * в любой точке мира *, которая является фиксированной длиной и UTF-8. –

+0

Мне просто нужно иметь все charcters в utf-8 –

ответ

2

UTF-8 - это кодировка, которая будет всегда использовать переменное количество байтов; сколько зависит от кодовых страниц Unicode входного текста.

Если вам нужна кодировка с фиксированной длиной, которая может обрабатывать Юникод, используйте UTF-32 (UTF-16 по-прежнему использует либо 2, либо 4 байта на код).

Обратите внимание, что кодировки UTF-16 и UTF-32 включают в себя блок кода Byte Order Mark; начальный код U+FEFF ZERO WIDTH NO-BREAK SPACE, который позволяет декодеру знать, были ли байты произведены в маленьком или большом порядке. Этот код будет всегда 4 байта для UTF-32, поэтому ваш результат будет 4 + (число символов 4 *).

Вы можете кодировать в определенном порядке байтов путем добавления -le или -be к кодеку, и в этом случае спецификация опущена:

>>> 'Hello world'.encode('utf-32') 
b'\xff\xfe\x00\x00H\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00 \x00\x00\x00w\x00\x00\x00o\x00\x00\x00r\x00\x00\x00l\x00\x00\x00d\x00\x00\x00' 
>>> 'Hello world'.encode('utf-32-le') 
b'H\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00 \x00\x00\x00w\x00\x00\x00o\x00\x00\x00r\x00\x00\x00l\x00\x00\x00d\x00\x00\x00' 
>>> 'Hello world'.encode('utf-32-be') 
b'\x00\x00\x00H\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00 \x00\x00\x00w\x00\x00\x00o\x00\x00\x00r\x00\x00\x00l\x00\x00\x00d' 
+0

'\ uffff'.encode (' utf-32 ') дает b' \ xff \ xfe \ x00 \ x00 \ xff \ xff \ x00 \ x00 'и ' \ u0123'.encode ('utf-32') дает b '\ xff \ xfe \ x00 \ x00 # \ x01 \ x00 \ x00'. Что делает #? –

+0

@ Владимир Шевяков: опять же, это спецификация. Я обновлю (но будьте терпеливы, в поезде и связность переменная). –

+0

Хорошо, спасибо! Работает сейчас :-) –

Смежные вопросы