base64.b16encode / b16decode

RFC 4648 Base16 is hex in uppercase. The decoder rejects lowercase (unless casefold=True), spaces and an odd number of digits — bytes.fromhex is the forgiving alternative.

base64 functionPython 2.4+Live demo
Common call
base64.b16encode(data) · base64.b16decode(text, casefold=True)
Returns
bytes — b'6869' / b'hi'
Replaces
binascii.hexlify(data).upper()
Watch out
Lowercase hex fails without casefold=True — and bytes.hex() produces lowercase
base64.b16decode(ss — Data to encode, or hex text to decode (only 0–9 A–F, even length).type: bytes-like (encode) · bytes-like | ASCII str (decode) · required, casefoldcasefold — Decode only: accept lowercase a–f.type: bool · default: False=False)
→ bytes

Demo

Live evaluation
b16encode next to bytes.hex(): same digits, different case and type.
Try:
Inputs
textstrany text
Code
import base64
data = 'Hello'.encode()
(base64.b16encode(data), data.hex())
Result
(b'48656C6C6F', '48656c6c6f')

b16decode checks the characters first and the length second: lowercase and spaces give "Non-base16 digit found", while "486" passes the character check and then fails in binascii with "Odd-length string". casefold=True uppercases the input before checking, so it fixes lowercase but not spaces.

Parameters

NameTypeRequiredDescription
sbytes-like (encode) · bytes-like | ASCII str (decode)yesData to encode, or hex text to decode (only 0–9 A–F, even length).
casefoldboolno (False)Decode only: accept lowercase a–f.

Return value

bytes — Encode: uppercase hex digits as ASCII bytes. Decode: the original bytes.

Common patterns

Hex of a hash, uppercase
hexdigest() is lowercase; b16encode gives the uppercase form some APIs want.
import base64, hashlib
base64.b16encode(hashlib.sha256(data).digest()).decode('ascii')
Lenient hex parsing
bytes.fromhex accepts either case and whitespace between bytes.
raw = bytes.fromhex('48 65 6c 6c 6f')

Examples

1. Encode
import base64 base64.b16encode(b'\x00\xffhi')
Returns
b'00FF6869'
2. bytes.hex is lowercase
b'\x00\xffhi'.hex()
Returns
'00ff6869'
3. Decode
import base64 base64.b16decode('48656C6C6F')
Returns
b'Hello'
4. Lowercase rejected
import base64 base64.b16decode('48656c6c6f')
Returns
binascii.Error: Non-base16 digit found
5. casefold=True
import base64 base64.b16decode('48656c6c6f', casefold=True)
Returns
b'Hello'
6. Odd length
import base64 base64.b16decode('486')
Returns
binascii.Error: Odd-length string

Pitfalls

1. Decoding the output of bytes.hex()
hex() and hexdigest() are lowercase; b16decode wants uppercase by default.
b16decode(hex())
import base64
base64.b16decode(b'\xca\xfe'.hex())
binascii.Error: Non-base16 digit found
casefold=True
import base64
base64.b16decode(b'\xca\xfe'.hex(), casefold=True)
b'\xca\xfe'
2. Spaced hex dumps
Spaces are not Base16 digits. bytes.fromhex skips whitespace between byte pairs.
b16decode
import base64
base64.b16decode('DE AD BE EF')
binascii.Error: Non-base16 digit found
bytes.fromhex
bytes.fromhex('DE AD BE EF')
b'\xde\xad\xbe\xef'

When to use

Use it
  • Protocols that specify RFC 4648 Base16 (uppercase)
  • Strict validation of hex input
Reach for something else
  • Everyday hex → bytes.hex() and bytes.fromhex() need no import
  • Compact output → Base64 adds a third to the size, hex doubles it

Notes

CPython impl
b16encode = binascii.hexlify(s).upper(); b16decode checks re.search(b"[^0-9A-F]") and then calls binascii.unhexlify
Exceptions
binascii.Error: "Non-base16 digit found" (character check) or "Odd-length string" (from unhexlify)

FAQ

The case and the type: b16encode returns uppercase bytes (b"6869"), bytes.hex() returns a lowercase str ("6869"). The digits are the same.