I have a long Hex string that represents a series of values of different types. I wish to convert this Hex String into a byte array so that I can shift each value out and convert it into its proper data type.
8 Answers
Suppose your hex string is something like
>>> hex_string = "deadbeef"
Convert it to a string (Python ≤ 2.7):
>>> hex_data = hex_string.decode("hex")
>>> hex_data
"\xde\xad\xbe\xef"
or since Python 2.7 and Python 3.0:
>>> bytes.fromhex(hex_string) # Python ≥ 3
b'\xde\xad\xbe\xef'
>>> bytearray.fromhex(hex_string)
bytearray(b'\xde\xad\xbe\xef')
Note that bytes is an immutable version of bytearray.
- 87,612
- 28
- 135
- 198
-
37If anyone is looking for hex `string` -> `bytes` object, it's ` bytes.fromhex("000102030405060708090A0B0C0D0E0F")` which yields `b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'`. Not posting as an answer since question asks for byte array, but posting here since it's the first hit I got when searching for hext to bytes. – matrixanomaly Jul 29 '15 at 15:38
-
@Hubro Actually, `hex_string.decode("hex")` is working on Python 2.7. I just tested on my `Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32`. – MewX Oct 22 '17 at 01:10
-
-
6**Note** that `bytes.fromhex` throws an error when the input string has an odd number of characters: `bytes.fromhex("aab")` → `ValueError: non-hexadecimal number found in fromhex() arg at position 3`. – Константин Ван Jul 24 '18 at 17:35
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.
- 1,669
- 1
- 10
- 5
-
4
-
7This works in Python 3, whereas `hex_string.decode("hex")` does not. – Eric O Lebigot Feb 22 '15 at 10:22
provided I understood correctly, you should look for binascii.unhexlify
import binascii
a='45222e'
s=binascii.unhexlify(a)
b=[ord(x) for x in s]
- 7,044
- 1
- 24
- 41
-
4I agree that `unhexlify` is the most efficient way to go here, but would suggest that `b = bytearray(s)` would be a better than using `ord`. As Python has a built-in type just for arrays of bytes I'm surprised no one is using it – Scott Griffiths Apr 13 '11 at 15:03
Assuming you have a byte string like so
"\x12\x45\x00\xAB"
and you know the amount of bytes and their type you can also use this approach
import struct
bytes = '\x12\x45\x00\xAB'
val = struct.unpack('<BBH', bytes)
#val = (18, 69, 43776)
As I specified little endian (using the '<' char) at the start of the format string the function returned the decimal equivalent.
0x12 = 18
0x45 = 69
0xAB00 = 43776
B is equal to one byte (8 bit) unsigned
H is equal to two bytes (16 bit) unsigned
More available characters and byte sizes can be found here
The advantages are..
You can specify more than one byte and the endian of the values
Disadvantages..
You really need to know the type and length of data your dealing with
- 459
- 4
- 9
-
2Disadvantages: that is a byte string, not a hex string, so this is not an answer to the question. – qris Feb 06 '15 at 13:29
-
It is an answer to the 2nd part of the question "... so that I can shift each value out and convert it into its proper data type". – Rainald62 May 06 '19 at 16:02
You can use the Codecs module in the Python Standard Library, i.e.
import codecs
codecs.decode(hexstring, 'hex_codec')
You should be able to build a string holding the binary data using something like:
data = "fef0babe"
bits = ""
for x in xrange(0, len(data), 2)
bits += chr(int(data[x:x+2], 16))
This is probably not the fastest way (many string appends), but quite simple using only core Python.
- 378,987
- 63
- 458
- 590
def hex2bin(s):
hex_table = ['0000', '0001', '0010', '0011',
'0100', '0101', '0110', '0111',
'1000', '1001', '1010', '1011',
'1100', '1101', '1110', '1111']
bits = ''
for i in range(len(s)):
bits += hex_table[int(s[i], base=16)]
return bits
- 931
- 15
- 18
A good one liner is:
byte_list = map(ord, hex_string)
This will iterate over each char in the string and run it through the ord() function. Only tested on python 2.6, not too sure about 3.0+.
-Josh
- 662
- 4
- 13
-
-
Click the outline of the checkmark next to this answer if it's the right one! :) – jathanism Apr 13 '11 at 13:54
-
2This doesn't convert hex - it converts each character of a string to an integer. For hex each pair of characters would represent a byte. You might as well just say `byte_list = bytearray(hex_string)` – Scott Griffiths Apr 13 '11 at 15:11