2015-08-26 2 views
2

У меня есть байтовая строка из соединения сокета:Как преобразовать массив bytestring в шестнадцатеричную строку в Python 3.4?

>>> var 
b'\xb5\x1a' 

Как я могу преобразовать это (прямой порядок байт порядка) в строку шестнадцатеричной:

>>> var2 
0x1AB5 

Я попытался:

>>> var.decode('utf-8') 
Traceback (most recent call last):File "<stdin>", line 1, in <module> UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb5 in position 0: invalid start byte 

>>> var.from_bytes(2,'little') 
Traceback (most recent call last):File "<stdin>", line 1, in <module> AttributeError: 'bytes' object has no attribute 'from_bytes' 

ответ

2

Метод int.from_bytes поможет.

int.from_bytes (байт, порядком байтов, *, подписанная = False) ->INT

Возвращает целое число, представленное заданного массива байтов.

...

Если это порядком байтов «мало», самый старший байт в конце массива байтов.

Он преобразует байт в целое:

In [1]: int.from_bytes(b'\xb5\x1a', 'little') # 'little' for little-endian order 
Out[1]: 6837 

Затем вы можете использовать hex

In [2]: hex(int.from_bytes(b'\xb5\x1a', 'little')) 
Out[2]: '0x1ab5' 

или format(..., '#x')

In [3]: format(int.from_bytes(b'\xb5\x1a', 'little'), '#x') 
Out[3]: '0x1ab5' 

получить шестнадцатеричное представление.

Другие растворы включают base64.b16encode

In [4]: import base64 

In [5]: '0x' + base64.b16encode(b'\xb5\x1a'[::-1]).decode('ascii') 
Out[5]: '0x1AB5' 

и binascii.hexlify:

In [24]: '0x' + binascii.hexlify(b'\xb5\x1a'[::-1]).decode('ascii') 
Out[24]: '0x1ab5' 

Некоторые тайминги для bytestr = b'\xb5\x1a':

In [32]: %timeit hex(int.from_bytes(bytestr, 'little')) 
1000000 loops, best of 3: 267 ns per loop 

In [33]: %timeit format(int.from_bytes(bytestr, 'little'), '#x') 
1000000 loops, best of 3: 465 ns per loop 

In [34]: %timeit '0x' + base64.b16encode(bytestr[::-1]).decode('ascii') 
1000000 loops, best of 3: 746 ns per loop 

In [35]: %timeit '0x' + binascii.hexlify(bytestr[::-1]).decode('ascii') 
1000000 loops, best of 3: 545 ns per loop 

При bytestr = b'\xb5\x1a' * 100:

In [37]: %timeit hex(int.from_bytes(bytestr, 'little')) 
1000000 loops, best of 3: 992 ns per loop 

In [38]: %timeit format(int.from_bytes(bytestr, 'little'), '#x') 
1000000 loops, best of 3: 1.2 µs per loop 

In [39]: %timeit '0x' + base64.b16encode(bytestr[::-1]).decode('ascii') 
1000000 loops, best of 3: 1.38 µs per loop 


In [40]: %timeit '0x' + binascii.hexlify(bytestr[::-1]).decode('ascii') 
1000000 loops, best of 3: 983 ns per loop 

int.from_bytes является (предсказуемо) быстро для коротких строк байт, binascii.hexlify быстро для более длинных строк байтов.

Смежные вопросы