Понимание представления Python для base64 декодированных байтов - PullRequest
1 голос
/ 19 марта 2019

Контекст: я пробую программу, которая захватывает некоторые сообщения MQTT и затем регистрирует их.При этом я сталкиваюсь со странной проблемой, и мне нужна помощь в этом.

Во входящих сообщениях я получаю одну строку в кодировке base64.Моя программа пытается декодировать и анализировать двоичные данные, чтобы выяснить некоторые заголовки пакета.Код, который я имею, выглядит следующим образом:

result = base64.standard_b64decode("AO/Nq4lnRSMBZXMnLHcKXhSObYxiFvY=")

Вывод результата выглядит следующим образом:

b"\x00\xef\xcd\xab\x89gE#\x01es',w\n^\x14\x8em\x8cb\x16\xf6"

Если та же операция выполняется с использованием реализации nodeJS, вывод будет совершенно другим:

<Buffer 00 ef cd ab 89 67 45 23 01 65 73 27 2c 77 0a 5e 14 8e 6d 8c 62 16 f6>

Я прочитал несколько других ссылок в переполнении стека и не мог понять, почему существует разница.Ссылка NodeJS base64 против Python base64 имеет некоторые допустимые точки в отношении кодировки, которая была сделана, поэтому то, что Python делает здесь, не является неправильным.

После прочтения я нашел еще один совет, в котором использовалась функция binascii.Итак, если я применяю эту логику, мой вывод выглядит точно так же, как вывод NodeJS!

import binascii
binascii.hexlify(result)
b'00efcdab89674523016573272c770a5e148e6d8c6216f6'

Теперь мой вывод выглядит так, как я хочу.Однако есть еще одна новая проблема.Вывод декодирования base64 был в формате b '\ x00', а вывод hexlify - b'0 '.Из-за этой разницы я не могу запустить другую часть моего кода, которая разбивает этот выходной байт на байт для создания struct.unpack в различных форматах в зависимости от заголовка пакета.

Есть ли какая-либо помощь, которую яможно продолжить?

Ответы [ 2 ]

1 голос
/ 19 марта 2019

Если я хорошо понимаю, вас смущает форматирование байтов в Python.

В основном, при отображении байта в Python, если этот байт соответствует символу ASCII, вместо числового значения используется символ,На самом деле результаты в Python и NodeJS одинаковы, отличаются только представления.

Вы можете проверить это, совместив два представления:

b"    \x00\xef\xcd\xab\x89  g  E  #\x01  e  s  '  ,  w \n  ^\x14\x8e  m\x8c  b\x16\xf6"
<Buffer 00  ef  cd  ab  89 67 45 23  01 65 73 27 2c 77 0a 5e  14  8e 6d  8c 62  16  f6>

Как видите, значения идентичныза исключением:

67 -> g
45 -> E
23 -> #
65 -> e
73 -> s
27 -> '
2c -> ,
0a -> \n
5e -> ^
6d -> m

Дело в том, что каждое отображаемое выше шестнадцатеричное значение соответствует символу в таблице ASCII.

Вы можете легко проверить это в интерпретаторе Python (ord даетASCII код данного символа и hex преобразует его в шестнадцатеричное представление):

>>> hex(ord('g'))
'0x67'
>>> hex(ord('E'))
'0x45'
>>> hex(ord('#'))
'0x23'

Наконец, вы можете даже получить точно такое же представление, как NodeJS в нескольких строках Python:

>>> bytes = b"\x00\xef\xcd\xab\x89gE#\x01es',w\n^\x14\x8em\x8cb\x16\xf6"
>>> print('<Buffer {}>'.format(' '.join([format(c, '02x') for c in bytes])))
<Buffer 00 ef cd ab 89 67 45 23 01 65 73 27 2c 77 0a 5e 14 8e 6d 8c 62 16 f6>
0 голосов
/ 19 марта 2019

base64.standard_b64decode возвращает объект bytes, представляющий собой неизменяемую последовательность отдельных байтов. На это указывает буква b перед ".

Из документов :

Литералы байтов всегда имеют префикс 'b' или 'B'; они создают экземпляр типа bytes вместо типа str. Они могут содержать только символы ASCII; байты с числовым значением 128 или более должны быть выражены с помощью экранирования.

Здесь вы видите ASCII-представление объекта bytes, а не строку.

Чтобы преобразовать объект bytes в строку, аналогичную результату, который вы получаете от nodeJS, вы можете использовать bytes метод объекта hex:

import base64

result = base64.b64decode(b"AO/Nq4lnRSMBZXMnLHcKXhSObYxiFvY=")

print(result.hex())

>>> 00efcdab89674523016573272c770a5e148e6d8c6216f6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...