Как я могу преобразовать байты в целую шестнадцатеричную строку? - PullRequest
0 голосов
/ 22 мая 2018
a1 = b'\x01\x02\x41'

\x41 равно A

, и когда я печатаю str(a1), я получаю

b'\x01\x02A'

, как я могу получить исходную шестнадцатеричную строку?

Я хочу получить:

\x01\x02\x41

Я использую эту строку для redis-cli --pipe.

Я не хочу, чтобы python печатал для меня преобразованную строку.

Как я мог это сделать?

Теперь я делаю так:

def convert(i:bytes):
    result = list()
    for j in i:
        result.append('\\x%s' % bytes([j]).hex())
    return ''.join(result)

Это слишком уродливо.Есть ли лучший способ?

кстати.

Это мой сценарий redis-cli --pipe:

SET "\xda\xb8\xe6\xc0\x79\x62\xea\x06\xde\x9e\xb0\x4e\x68\xde\x0b\x62" "\x00\x42\xdc\x06\x03\x00\x00\x00"
SET "\x68\xfa\xfc\x03\x36\x99\xb0\x56\xb4\x00\xaf\x61\x42\xe0\x30\x42" "\x01\x42\xdc\x06\x03\x00\x00\x00"
SET "\x40\x98\xb9\x8f\xd8\x4e\x2e\x32\x40\x09\xca\xa4\x55\x52\xde\x7f" "\x02\x42\xdc\x06\x03\x00\x00\x00"
SET "\xd0\x75\xdf\x46\x36\xd0\xb4\xed\xcc\xed\xd6\x27\xf7\xd9\xc5\xa5" "\x03\x42\xdc\x06\x03\x00\x00\x00"

Я использую его следующим образом:

cat sample.redis | redis-cli --pipe

1 Ответ

0 голосов
/ 22 мая 2018

При переборе значения bytes вы получаете целые числа;они тривиально преобразуются в шестнадцатеричные обозначения:

def convert(value: bytes):
    return ''.join([f'\\x{b:02x}' for b in value])

Обратите внимание, что получается строка с буквенными обратными слешами, x символами и шестнадцатеричными символами .Это больше не значение bytes.

Демо:

>>> print(convert(b'\x01\x02\x41'))
\x01\x02\x41

Просто чтобы убедиться, вам не нужно беспокоиться о значении bytes ,Представление repr() объекта bytes всегда будет использовать символы ASCII, когда значение байта совпадает с печатаемой кодовой точкой ASCII.Это не значит, что значение изменилось.b'\x01\x02\x41' равно b'\x01\x02A'.Протокол Redis ничего не знает о \x<HH> escape-последовательностях, поэтому не пытайтесь отправить указанную выше строку по проводам.

Создаваемые escape-последовательности: строка оболочки bashпоследовательности , и, как и строки Python, вам не нужно использовать экранированные символы .Как и в Python, для Bash строки "\x01\x02A" и "\x01\x02\x41" имеют одинаковые значения.Они имеют смысл только при передаче строк ключей и значений в командной строке, а не в текстовом файле, который вы перенаправляете на redis-cli.

Кроме того, обратите внимание, что команда redis-cli --pipe принимает необработанный ввод протокола Redis , а не синтаксис команды Redis, см. массовая вставка Redis документация .Этот протокол не использует \xhh последовательности, так как он не использует обозначения оболочки.

Вместо этого используйте следующую функцию для генерации необработанных SET команд:

def raw_protocol(cmd: str, *args: bytes):
    return b'\r\n'.join([
        f'*{len(args) + 1}\r\n${len(cmd)}\r\n{cmd}'.encode(),
        *(bv for a in args for bv in (b'$%d' % len(a), a)),
        b''
    ])

Для команды SET введите raw_protocol('SET', keybytes, valuebytes) и запишите полученные двоичные данные в файл, открытый в двоичном режиме.

...