Как ввести необработанные байты bytearray?

Из-за отсутствия лучшей формулировки я использовал «необработанные байты» для обозначения bytearray(b'\xDE\xAD\xBE\xEF'), а не «без необработанных байтов» как bytearray(b'DEADBEEF').

Я поддерживаю кодовую базу, которая выполняет различные манипуляции с байтами для bytearray() параметров. Чтобы они работали правильно, они должны быть «сырыми байтами». Краткий пример, почему это важно:

raw_b = bytearray(b'\xde\xad\xbe\xef')
raw_b.reverse()
print(raw_b) -> bytearray(b'\xef\xbe\xad\xde')

не то же самое, что

b = bytearray(b'DEADBEEF')
b.reverse()
print(b) -> bytearray(b'FEEBDAED')

И есть много других вещей, которые идут не так, как индексация значений и т. д.

И raw_b, и b в приведенном выше примере относятся к типу bytearray, поэтому ввод bytes мне не помогает. Функции, которым требуются эти необработанные байты, в настоящее время имеют следующую конструкцию повсюду, чтобы гарантировать, что параметр действительно находится в необработанных байтах.

try:
    value = binascii.unhexlify(param)
except binascii.Error:
    #already raw bytes
    pass

Как мне вводить необработанные байты, чтобы избавиться от этого мусора?


person ixje    schedule 30.11.2018    source источник
comment
Мне непонятно, чем отличаются необработанные строки байтов. Во всех этих случаях у вас есть последовательности байтов.   -  person tripleee    schedule 03.12.2018
comment
Ты не понял; нет различия в необработанных байтах. В одном вы использовали escape-последовательности, а в другом — прямые буквы ASCII. Они определяют совершенно разные ценности.   -  person Martijn Pieters    schedule 04.12.2018
comment
@MartijnPieters из вашего ответа в дублирующей ссылке: объекты байтов в основном содержат последовательность целых чисел в диапазоне 0-255. Если это так, то почему b'A' == 0x41 возвращает False? Это сигнализирует мне, что это не uint8, как вы говорите. Что мне не хватает в этой логике?   -  person ixje    schedule 04.12.2018
comment
@ixje b'A' — это полная последовательность, а не отдельное целое число! b'A'[0] == 0x41 верно, как и b'A' == bytes([0x41]).   -  person Martijn Pieters    schedule 04.12.2018
comment
Мой разум, должно быть, действительно застрял в классификации 1 символа как полубайта и 2 как байта при чтении значений, связанных с byte(s). Теперь я понимаю, что вы говорите, спасибо.   -  person ixje    schedule 04.12.2018


Ответы (1)


b'DEADBEEF' — это строка из 8 байтов, они вообще не интерпретируются как шестнадцатеричные значения. Это как вы написали: bytearray([0x44, 0x45, 0x41, 0x44, 0x42, 0x45, 0x45, 0x46]).

binascii.unhexlify() фактически преобразует строку шестнадцатеричных цифр ASCII в двоичные данные.

Разница в том, как они печатаются («A» вместо «\ x41»), заключается в том, что python печатает печатные символы как символы, но представляет их как экранированные шестнадцатеричные константы, если они не печатаются.

Таким образом, bytearray(b'\xde\xad\xbe\xef') и bytearray(b'DEADBEEF') ЯВЛЯЮТСЯ двумя массивами байтов, но с разным содержимым - в частности, len() первого - 4, второго - 8.

Ваша кодовая база работает правильно с обоими, но вам нужно передавать правильные данные: я бы не стал встраивать unhexlify() во всю вашу структуру, но я бы позаботился о том, чтобы вы передавали в нее правильные данные.

Другими словами: вы не можете передать bytearray([0x44, 0x45, 0x41, 0x44, 0x42, 0x45, 0x45, 0x46]) вместо bytearray([0xDE, 0xAD, 0xBE, 0xEF]) и ожидать, что результат будет таким же!

person Sigi    schedule 03.12.2018
comment
Это не отвечает на вопрос. Я знаю, что они не одинаковы, поэтому там есть binascii.unhexlify, и поэтому я заранее спрашиваю, как их отличить. - person ixje; 04.12.2018
comment
так что вы просите? Как библиотека может знать, что 0x44,0x45 нужно оставить прежним или преобразовать в 0xDE внутри? Это ответственность вызывающей стороны: различия между необработанными байтами и отсутствием необработанных байтов не существует. Единственное различие, которое я вижу, заключается в содержании печатных символов. Но я не ожидаю достаточного различия для библиотеки, работающей с двоичными данными... однако это зависит от вашего конкретного приложения: если это имеет для вас смысл... тогда вам не о чем спрашивать об этом. - person Sigi; 04.12.2018