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
Answer from Felix Weis on Stack OverflowSince 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
Use the binascii module:
>>> import binascii
>>> binascii.hexlify('foo'.encode('utf8'))
b'666f6f'
>>> binascii.unhexlify(_).decode('utf8')
'foo'
See this answer: Python 3 string to hex
Need some help with converting hex to bytearray for long strings
arrays - How to convert hexadecimal string to bytes in Python? - Stack Overflow
Python: How to convert a string containing hex bytes to a hex string - Stack Overflow
String to HEX
Hi all,
I'm working with the API for The Things Network and I have a number of fields that expect HEX as their input. These are then matched to the equivalent values sent by the LoRaWAN devices for "shared key" authentication.
As an example, there is a field called "net_key" which is a 16 byte string, and at the moment I'm just generating a string via secrets.hex(16), however on the end devices I need to convert that into an array with each of the couplets split out, which then needs to be converted into a byte array
For example, if the hex call returns aabbccddeeff00112233445566778899, then the byte array should look like this:
['0xaa','0xbb','0xcc','0xdd','0xee','0xff','0x00','0x11','0x22','0x33', '0x44', '0x55','0x66','0x77','0x88','0x99']
Here's an example JSON payload for the API:
{
"end_device": {
"ids": {
"device_id": "test-device"
},
"session": {
"keys": {
"app_s_key": {
"key": "32079314899832864415563434004158"
}
},
"dev_addr": "3d72ba69"
}
},
"field_mask": {
"paths": [
"ids.device_id",
"session.keys.app_s_key.key",
"session.dev_addr"
]
}
}and here's what the device configuration should look like:
ttn_config = {
"devaddr": bytearray([0x3d, 0x72, 0xba, 0x69]),
"nwkey": bytearray([]),
"app": bytearray([0x32, 0x07, 0x93, 0x14, 0x89, 0x98, 0x32, 0x86, 0x44, 0x15, 0x56, 0x34, 0x34, 0x00, 0x41, 0x58])
"country": "EU",
}Is there a an easy way that I'm missing to convert between the two formats?
Suppose your hex string is something like
>>> hex_string = "deadbeef"
Convert it to a bytearray (Python 3 and 2.7):
>>> bytearray.fromhex(hex_string)
bytearray(b'\xde\xad\xbe\xef')
Convert it to a bytes object (Python 3):
>>> bytes.fromhex(hex_string)
b'\xde\xad\xbe\xef'
Note that bytes is an immutable version of bytearray.
Convert it to a string (Python ≤ 2.7):
>>> hex_data = hex_string.decode("hex")
>>> hex_data
"\xde\xad\xbe\xef"
There is a built-in function in bytearray that does what you intend.
bytearray.fromhex("de ad be ef 00")
It returns a bytearray and it reads hex strings with or without space separator.
In all versions of Python, you can use the function
binascii.a2b_hex() (also known as binascii.unhexlify()):
>>> import binascii
>>> s = '356a192b7913b04c54574d18c28d46e6395428ab'
>>> binascii.a2b_hex(s)
'5j\x19+y\x13\xb0LTWM\x18\xc2\x8dF\xe69T(\xab'
In Python 3.x, you can use bytes.fromhex(s).
In Python 2.x, you can use the hex str-to-str codec:
>>> s.decode("hex")
'5j\x19+y\x13\xb0LTWM\x18\xc2\x8dF\xe69T(\xab'
The codec internally calls binascii.a2b_hex().
With binascii module:
>>> from binascii import unhexlify
>>> s = '356a192b7913b04c54574d18c28d46e6395428ab'
>>> unhexlify(s)
'5j\x19+y\x13\xb0LTWM\x18\xc2\x8dF\xe69T(\xab'