Функция Python — bytearray со строковым литералом

#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')      # -> '字'