binascii.unhexlify() (alias a2b_hex) converts a hex digit string to bytes. It is older than bytes.fromhex() and still appears in networking, crypto, and legacy codebases.
This page explains when unhexlify is the right tool and how it differs from bytes.fromhex. Method overview: Python hex → string methods. fromhex details: bytes.fromhex() deep dive.
Core API
import binascii
print(binascii.unhexlify("48656c6c6f")) # b'Hello'
print(binascii.a2b_hex("48656c6c6f")) # same
print(binascii.hexlify(b"Hello")) # b'48656c6c6f'
print(binascii.hexlify(b"Hello").decode()) # '48656c6c6f'
hexlify returns bytes of ASCII hex digits. Decode to str if you need a normal text string.
Strict about whitespace
import binascii
binascii.unhexlify("48656c6c6f") # OK
# binascii.unhexlify("48 65 6c") # binascii.Error
clean = "".join("48 65 6c 6c 6f".split())
print(binascii.unhexlify(clean)) # b'Hello'
Unlike bytes.fromhex, spaces are errors. That strictness is useful in protocols where unexpected whitespace should fail closed.
Errors you should handle
import binascii
def parse_hex(s: str) -> bytes:
s = "".join(s.split())
try:
return binascii.unhexlify(s)
except binascii.Error as exc:
raise ValueError("invalid hex payload") from exc
parse_hex("deadbeef")
# parse_hex("deadbee") # odd length → ValueError
# parse_hex("zz") # non-hex → ValueError
When unhexlify beats fromhex
- Code already imports
binasciifor CRC, base64, or hexlify. - You want whitespace to be illegal without extra flags.
- You maintain libraries that historically documented
a2b_hex/b2a_hex.
For greenfield Python 3 application code, bytes.fromhex is usually clearer. Functionally, both produce the same bytes for the same clean hex string.
Round-trip pattern
import binascii
payload = {"iv": binascii.hexlify(b"\x01\x02\x03\x04").decode("ascii")}
iv = binascii.unhexlify(payload["iv"])
assert iv == b"\x01\x02\x03\x04"
Common in JSON configs: store binary fields as hex text, parse back with unhexlify.
Text decoding is still your job
import binascii
raw = binascii.unhexlify("e4bda0e5a5bd")
print(raw.decode("utf-8")) # 你好
Hex ↔ bytes is encoding-agnostic. Character encoding applies only when interpreting bytes as text.
Try conversions online: Hex to String · String to Hex. Concept refresher: What is hexadecimal encoding?.