What's the Correct Way to Convert Bytes to a Hex String in Python 3

What's the correct way to convert bytes to a hex string in Python 3?

Since Python 3.5 this is finally no longer awkward:

>>> b'\xde\xad\xbe\xef'.hex()
'deadbeef'

and reverse:

>>> bytes.fromhex('deadbeef')
b'\xde\xad\xbe\xef'

works also with the mutable bytearray type.

Reference: https://docs.python.org/3/library/stdtypes.html#bytes.hex

Python3 bytes to hex string

You simply want to decode from ASCII here, your bytestring is already representing hexadecimal numbers, in ASCII characters:

>>> a = b'067b'
>>> a.decode('ascii')
'067b'

Everything you tried is interpreting the bytes as numeric data instead, either as hexadecimal numbers representing bytes or as bytes representing numeric data.

So your first attempt takes the value 06 as a hexadecimal number and turns that into the byte value 6, and 7b is turned into the byte value 123, which is the ASCII codepoint for the { character.

In your second attempt you are converting each byte to a hexadecimal representation of its numeric value. The 0 byte being interpreted as the integer number 48 (the ASCII codepoint for the '0' character), which is 30 in hexadecimal. '6' is 54, or 36 in hex, etc.

What is the correct way to convert bytes to a hex string in Python 3?

Bytes objects have the "hex" method:

return b.hex()

Byte Array to Hex String

Using str.format:

>>> array_alpha = [ 133, 53, 234, 241 ]
>>> print ''.join('{:02x}'.format(x) for x in array_alpha)
8535eaf1

or using format

>>> print ''.join(format(x, '02x') for x in array_alpha)
8535eaf1

Note: In the format statements, the 02 means it will pad with up to 2 leading 0s if necessary. This is important since [0x1, 0x1, 0x1] i.e. (0x010101) would be formatted to "111" instead of "010101"

or using bytearray with binascii.hexlify:

>>> import binascii
>>> binascii.hexlify(bytearray(array_alpha))
'8535eaf1'

Here is a benchmark of above methods in Python 3.6.1:

from timeit import timeit
import binascii

number = 10000

def using_str_format() -> str:
return "".join("{:02x}".format(x) for x in test_obj)

def using_format() -> str:
return "".join(format(x, "02x") for x in test_obj)

def using_hexlify() -> str:
return binascii.hexlify(bytearray(test_obj)).decode('ascii')

def do_test():
print("Testing with {}-byte {}:".format(len(test_obj), test_obj.__class__.__name__))
if using_str_format() != using_format() != using_hexlify():
raise RuntimeError("Results are not the same")

print("Using str.format -> " + str(timeit(using_str_format, number=number)))
print("Using format -> " + str(timeit(using_format, number=number)))
print("Using binascii.hexlify -> " + str(timeit(using_hexlify, number=number)))

test_obj = bytes([i for i in range(255)])
do_test()

test_obj = bytearray([i for i in range(255)])
do_test()

Result:

Testing with 255-byte bytes:
Using str.format -> 1.459474583090427
Using format -> 1.5809937679100738
Using binascii.hexlify -> 0.014521426401399307
Testing with 255-byte bytearray:
Using str.format -> 1.443447684109402
Using format -> 1.5608712609513171
Using binascii.hexlify -> 0.014114164661833684

Methods using format do provide additional formatting options, as example separating numbers with spaces " ".join, commas ", ".join, upper-case printing "{:02X}".format(x)/format(x, "02X"), etc., but at a cost of great performance impact.

Python converting bytes to hex and back

I assume the image raw hex includes padded 0s? If that's the case, these padded 0s are being lost when converting from the ints back to hex. This can be fixed as follows:

reversed_hex = ''.join([format(int(i), '02x') for i in data])

Convert bytes to hex value

byte_value = b'F6F3F6F2'
high, low = byte_value[0:4], byte_value[4:]
print(high, low)

# Convert high, low into int
high_int = int(high, 16)
low_int = int(low, 16)

print(high_int)
print(low_int)

# now you can use those values like
im.putpixel((x,y),((high_int&0xF800) >> 8, (high_int&0x07E0) >> 3, (high_int&0x001F) <<3))
im.putpixel((x,y),((low_int&0xF800) >> 8, (low_int&0x07E0) >> 3, (low_int&0x001F) <<3))

How to create python bytes object from long hex string?

result = bytes.fromhex(some_hex_string)


Related Topics



Leave a reply



Submit