#python
Вопрос:
Изучая OpenCV в Python, я наткнулся на функцию bytearray (), которая возвращает массив байтов. Читая об этой функции в Интернете, я увидел пример, результат которого я не совсем понимаю. Образец можно найти здесь: https://www.geeksforgeeks.org/python-bytearray-function/
Код:
str = 'Geeksforgeeks'
array2 = bytearray(str, 'utf-16')
print(array2)
В результате получается:
bytearray(b'xffxfeGx00ex00ex00kx00sx00fx00ox00rx00gx00ex00ex00kx00sx00')
Хотя я понимаю, что x-это escape-последовательность, указывающая шестнадцатеричное значение, значения, следующие за ff, fe, 00 и т. Д., Для меня не имеют смысла, Когда я говорю о символах.
Например, строка начинается с кавычек, за которыми следует заглавная буква g, т. е. G.
Результатом функции bytearray является xfeG
У меня возникли трудности с отображением xfeG на заглавную букву G. Если мы предположим, что x указывает на следующее шестнадцатеричное число, я бы прочитал его как 0xfe = 254. Глядя на таблицу ASCII для этого числа, я получаю нечто совершенно отличное от G. и 0xfeG не существует.
Не мог бы кто-нибудь помочь мне с этим, потому что я немного заблудился.
Спасибо,
Комментарии:
1. Вы хотите ознакомиться с кодировкой UTF-16, например, на en.wikipedia.org/wiki/UTF-16 .
2. FEFF-это метка порядка байтов (BOM) массива байтов в кодировке UTF-16. В зависимости от конечного значения эти два байта могут быть перевернуты.
3. ` ‘G’.кодировать(‘utf16’)` -> >
b'xffxfeGx00'
— первые два байта являются меткой порядка байтов (BOM).
Ответ №1:
значения, следующие за ff, fe, 00 и т. Д., Не имеют смысла для меня, Когда я говорю о персонажах.
Это потому, что вы не знаете, как работает UTF-16.
16 в UTF-16 указывает, сколько битов используют символы, т. е. Каждый символ будет использовать 2 байта.
Когда у вас есть два байта A
и B
, вы можете физически разместить их как AB
(это называется «малый конец») или BA
(это «большой конец»). Это называется порядком байтов, и это важно знать для успешного преобразования байтов обратно в символы («декодирование») позже.
Для этого строка байтов начинается с метки порядка байтов («СПЕЦИФИКАЦИЯ»). xffxfe
является спецификацией для типа «маленький конец».
Таким символам, как G
, например, не нужны полные 16 бит, поэтому второй байт остается пустым ( x00
) и G
становится x47x00
. Python отображает символы для всех байтов, которые меньше 127, поэтому это отображается как Gx00
, но это одно и то же.
Литтл-эндианское кодирование:
b'xffxfeGx00ex00ex00kx00sx00fx00ox00rx00gx00ex00ex00kx00sx00'
'LE BOM |G |e |e |k |s |f |o |r |g |e |e |k |s '
Кодировка большого конца (обратите внимание на другую спецификацию):
b'xfexffx00Gx00ex00ex00kx00sx00fx00ox00rx00gx00ex00ex00kx00s'
'BE BOM | G| e| e| k| s| f| o| r| g| e| e| k| s'
Обе байтовые строки декодируются правильно .decode('UTF-16')
, потому что спецификация сообщает .decode()
о внутреннем расположении строки.
Другие символы занимают больше 16 бит. Например 字
, становится x57x5b
в малом конце UTF-16, который Python несколько бесполезно отображает как W[
.
b'x57x5b'.decode('UTF-16') # -> '字'
b'W['.decode('UTF-16') # -> '字'
Когда спецификация отсутствует, Python по умолчанию будет принимать «литтл-эндианский». В противном случае вам нужно четко указать тип:
b'[W'.decode('UTF-16-BE') # -> '字'