120

I have data stored in a byte array. How can I convert this data into a hex string?

Example of my byte array:

array_alpha = [ 133, 53, 234, 241 ]
2
  • 1
    related: What's the correct way to convert bytes to a hex string in Python 3? Commented Feb 24, 2016 at 16:03
  • This is not a "byte array". It is a list which contains integers. That said, the technique is the same - you can trivially create a bytes or bytearray object from this list first. Commented Nov 10, 2024 at 18:01

6 Answers 6

177

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.

Sign up to request clarification or add additional context in comments.

9 Comments

Yours last trick give me b'8535eaf1' on my system, what is b ?
@GrijeshChauhan, Are you using Python 3.x? In Python 3.x binascii.hexlify return bytes objects.
@GrijeshChauhan, See Built-in Types - Bytes.
For anyone else reading this: convert b'8535eaf1' to '8535eaf1' with b'8535eaf1'.decode('ascii')
@mkingston, You can omit the encoding: b'8535eaf1'.decode()
|
81

Consider the hex() method of the bytes type on Python 3.5 and up:

>>> array_alpha = [ 133, 53, 234, 241 ]
>>> print(bytes(array_alpha).hex())
8535eaf1

EDIT: it's also much faster than hexlify (modified @falsetru's benchmarks above)

from timeit import timeit
N = 10000
print("bytearray + hexlify ->", timeit(
    'binascii.hexlify(data).decode("ascii")',
    setup='import binascii; data = bytearray(range(255))',
    number=N,
))
print("byte + hex          ->", timeit(
    'data.hex()',
    setup='data = bytes(range(255))',
    number=N,
))

Result:

bytearray + hexlify -> 0.011218150997592602
byte + hex          -> 0.005952142993919551

3 Comments

Note that bytearray + hexlify returns data as bytes (b' 34567890aed'), while byte + hex returns it as a string (34567890aed)
It also takes an optional argument to specify a separator, so bytes(array_alpha).hex(' '), prints every byte with a space separating them
Just to add up to this answer, which would be my method of choice 9 out of 10 times, to unHEX back into a bytearray, you can use bytes.fromhex("<hex string>")
14
hex_string = "".join("%02x" % b for b in array_alpha)

2 Comments

thanks for providing an answer that also works with older versions of python (forced to use 2.5.1 here)
@Baldrickk Yeah, it's amazing how many off-topic answers there are. The question is tagged python2.7.
4

Or, if you are a fan of functional programming:

>>> a = [133, 53, 234, 241]
>>> "".join(map(lambda b: format(b, "02x"), a))
8535eaf1
>>>

Comments

3

If you have a numpy array, you can do the following:

>>> import numpy as np
>>> a = np.array([133, 53, 234, 241])
>>> a.astype(np.uint8).data.hex()
'8535eaf1'

7 Comments

This requires the import of an external library and does not address the fact that OP is working with bytes. This is not the most robust solution.
@MadPhysicist Removed the "robust solution" part. I still think a numpy solution is useful for others coming here from google (it's much more common to have data in a numpy matrix rather than as a byte array).
I still think that it is a good idea to answer OP's question instead of making a general post that may be useful to someone. It is very unlikely that someone searching Google for how to process numpy arrays is going to come to the question titled "Byte Array to Hex String".
This just a worse way of spelling bytearray([133, 53, 234, 241]).hex()
I think I misintepreted your answer. You mean "you can do this if you have a numpy array", not "you can do this with numpy as a tool"
|
3

For Python 3.6 and later: use f-strings

Python 3.6 and beyond supports f-strings (aka "formatted string literals") like this:

array_alpha = [ 133, 53, 234, 241 ]
>>> print(' '.join(f'{x:02x}' for x in array_alpha))
85 35 ea f1

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.