Reputation: 23
I have a bytestring from a socket connection:
>>> var
b'\xb5\x1a'
How can i convert this (little endian order) into a Hex string like:
>>> var2
0x1AB5
I tried:
>>> 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'
Upvotes: 2
Views: 1731
Reputation: 46593
The int.from_bytes
method will help.
int.from_bytes(bytes, byteorder, *, signed=False) -> int
Return the integer represented by the given array of bytes.
...
If byteorder is 'little', the most significant byte is at the end of the byte array.
It will convert bytes to integer:
In [1]: int.from_bytes(b'\xb5\x1a', 'little') # 'little' for little-endian order
Out[1]: 6837
Then you can use hex
In [2]: hex(int.from_bytes(b'\xb5\x1a', 'little'))
Out[2]: '0x1ab5'
In [3]: format(int.from_bytes(b'\xb5\x1a', 'little'), '#x')
Out[3]: '0x1ab5'
to get hexadecimal representation.
Other solutions include base64.b16encode
In [4]: import base64
In [5]: '0x' + base64.b16encode(b'\xb5\x1a'[::-1]).decode('ascii')
Out[5]: '0x1AB5'
and binascii.hexlify
:
In [24]: '0x' + binascii.hexlify(b'\xb5\x1a'[::-1]).decode('ascii')
Out[24]: '0x1ab5'
Some timings for 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
For 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
is (predictably) fast for small byte strings, binascii.hexlify
is fast for longer byte strings.
Upvotes: 2