Byte Array zu Hex String

Antworten:

114

Verwenden von str.format:

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

oder mit format

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

Hinweis: In den Formatanweisungen 02bedeutet dies, dass 0bei Bedarf bis zu 2 führende s aufgefüllt werden. Dies ist wichtig , da [0x1, 0x1, 0x1] i.e. (0x010101)formatiert werden würde "111"statt"010101"

oder bytearraymit binascii.hexlify:

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

Hier ist ein Benchmark der oben genannten Methoden 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()

Ergebnis:

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

Methoden formatzusätzliche Formatierungsoptionen liefern, wie zB Trennung von Zahlen mit Leerzeichen " ".join, Kommas ", ".join, Großbuchstaben Druck "{:02X}".format(x)/ format(x, "02X"), etc., aber zu einem Preis von großen Auswirkungen auf die Leistung.

falsetru
quelle
Dein letzter Trick gibt mir b'8535eaf1' auf meinem System, was ist b?
Grijesh Chauhan
1
@GrijeshChauhan, Verwenden Sie Python 3.x? In Python 3.x gibt binascii.hexlify bytesObjekte zurück.
Falsetru
Ja, mein Python ist 3.3.2. - return bytes objects- Byte Objekt bedeutet? so etwas wie ein intObjekt?
Grijesh Chauhan
3
@GrijeshChauhan, siehe Built-in Types - Bytes.
Falsetru
2
@mkingston, Sie können die Codierung weglassen:b'8535eaf1'.decode()
falsetru
32

Betrachten Sie die hex () -Methode des bytesTyps unter Python 3.5 und höher:

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

EDIT: Es ist auch viel schneller als hexlify(modifizierte @ falsetru Benchmarks oben)

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,
))

Ergebnis:

bytearray + hexlify -> 0.011218150997592602
byte + hex          -> 0.005952142993919551
orip
quelle
Beachten Sie, dass bytearray + hexlify Daten als Bytes zurückgibt (b '34567890aed'), während byte + hex sie als Zeichenfolge zurückgibt (34567890aed)
Antonin GAVREL
9
hex_string = "".join("%02x" % b for b in array_alpha)
irgendwie
quelle
3
Baldrickk
5

Wenn Sie ein Numpy-Array haben, können Sie Folgendes tun:

>>> import numpy as np
>>> a = np.array([133, 53, 234, 241])
>>> a.astype(np.uint8).data.hex()
'8535eaf1'
ostrokach
quelle
2
Dies erfordert den Import einer externen Bibliothek und berücksichtigt nicht die Tatsache, dass OP mit Bytes arbeitet. Dies ist nicht die robusteste Lösung.
Mad Physicist
@MadPhysicist Der Teil "Robuste Lösung" wurde entfernt. Ich denke immer noch, dass eine Numpy-Lösung für andere nützlich ist, die von Google hierher kommen (es ist viel üblicher, Daten in einer Numpy-Matrix zu haben, als als Byte-Array).
Ostrokach
1
Ich denke immer noch, dass es eine gute Idee ist, die Frage von OP zu beantworten, anstatt einen allgemeinen Beitrag zu verfassen, der für jemanden nützlich sein kann. Es ist sehr unwahrscheinlich, dass jemand, der Google nach der Verarbeitung von Numpy-Arrays durchsucht, auf die Frage mit dem Titel "Byte Array to Hex String" kommt.
Mad Physicist
1
Dies ist nur eine schlechtere Art der Rechtschreibungbytearray([133, 53, 234, 241]).hex()
Eric
1
Ich glaube, ich habe Ihre Antwort falsch interpretiert. Sie meinen "Sie können dies tun, wenn Sie ein Numpy-Array haben", nicht "Sie können dies mit Numpy als Werkzeug tun "
Eric
3

Oder wenn Sie ein Fan von funktionaler Programmierung sind:

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

quelle