108

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 ]
falsetru
  • 357,413
  • 63
  • 732
  • 636
Jamie Wright
  • 1,259
  • 3
  • 10
  • 11
  • 1
    related: [What's the correct way to convert bytes to a hex string in Python 3?](http://stackoverflow.com/q/6624453/4279) – jfs Feb 24 '16 at 16:03

5 Answers5

162

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.

Bojan P.
  • 942
  • 1
  • 10
  • 21
falsetru
  • 357,413
  • 63
  • 732
  • 636
68

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
orip
  • 73,323
  • 21
  • 116
  • 148
  • 1
    Note that bytearray + hexlify returns data as bytes (b' 34567890aed'), while byte + hex returns it as a string (34567890aed) – Antonin GAVREL Jun 03 '20 at 23:37
13
hex_string = "".join("%02x" % b for b in array_alpha)
kindall
  • 178,883
  • 35
  • 278
  • 309
6

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'
ostrokach
  • 17,993
  • 11
  • 78
  • 90
  • 3
    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. – Mad Physicist Jul 19 '17 at 22:10
  • @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). – ostrokach Jul 25 '17 at 14:52
  • 1
    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". – Mad Physicist Jul 25 '17 at 15:10
  • helped me as well. beautiful. – vidstige Dec 13 '17 at 19:23
  • 1
    This just a worse way of spelling `bytearray([133, 53, 234, 241]).hex()` – Eric Sep 05 '18 at 21:27
  • @Eric Unless you are starting off with a numpy "byte array". – ostrokach Sep 05 '18 at 21:47
  • 1
    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_" – Eric Sep 06 '18 at 07:20
3

Or, if you are a fan of functional programming:

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