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 leading0
s 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
Run Linux Grep Command from Python Subprocess
How Remove Camera Preview to Raspberry Pi
And' (Boolean) VS '&' (Bitwise) - Why Difference in Behavior with Lists VS Numpy Arrays
Custom Sorting in Pandas Dataframe
Getting an "Invalid Syntax" When Trying to Perform String Interpolation
Removing Elements That Have Consecutive Duplicates
Animated Sprite from Few Images
Keras, How to Get the Output of Each Layer
How to Get an Absolute File Path in Python
Tensorflow Not Found Using Pip
How to Specify Multiple Return Types Using Type-Hints
"Nameerror: Name '' Is Not Defined" After User Input in Python
Should Wildcard Import Be Avoided
Import CSV File as a Pandas Dataframe
Sending "User-Agent" Using Requests Library in Python