How to use the Base16 encoder
- Type or paste text into the input. The Base16 appears in the output as you type.
- Charset under the input decides how characters become bytes. UTF-8 is the default.
- To decode, click Base16 (RFC 4648) → Text above the tool, or the ⇄ Swap button, which also moves the current output into the input. Lowercase digits, spaces and colons in the input are accepted.
- Copy output or Download the result. The From and To menus switch to other formats, such as Base32 or Base64, for comparison.
For hex with separators, 0x prefixes or lowercase output, Text to Hex has those options.
Base16 and RFC 4648
RFC 4648 defines Base64, Base32 and Base16 side by side, and Base16 is the simplest of the three: it has no padding, line breaks or bit regrouping. Every byte is split into two 4-bit halves, and each half maps to one character. The RFC’s own test vectors:
| Input | Base16 |
|---|---|
| (empty) | (empty) |
f | 66 |
fo | 666F |
foo | 666F6F |
foob | 666F6F62 |
fooba | 666F6F6261 |
foobar | 666F6F626172 |
The output length is always exactly twice the number of bytes, so Base16 needs no padding character. Base64 and Base32 group several bytes per block and have to fill out the last block with =. The RFC overview lists where each of these encodings is specified.
Base16 vs Base32 vs Base64
The 12 bytes of Hello, world in each RFC 4648 encoding:
| Encoding | Output | Length |
|---|---|---|
| Base16 | 48656C6C6F2C20776F726C64 | 24 |
| Base32 | JBSWY3DPFQQHO33SNRSA==== | 24 (20 without padding) |
| Base64 | SGVsbG8sIHdvcmxk | 16 |
Base16 trades size for clarity. You can read the bytes straight off it and compare values digit by digit, and it survives any system that handles letters and digits, case-insensitive ones included. Base64 is a third shorter and is the default when the bytes have to travel inside JSON, email or URLs. The encoding comparison goes further, including Base58 and Base85.
Where you see Base16
- Hash digests and checksums, usually printed lowercase by
sha256sumand similar tools. - OpenPGP key fingerprints, which GnuPG prints as uppercase hex in groups of four.
- Test vectors in RFCs and other specifications, where unambiguous byte values matter more than length.
- Protocols and formats that need case-insensitive or purely alphanumeric data.
To move such a value into Base64, for example a digest that an API wants in Base64, use Hex to Base64; Base64 to Hex goes the other way.
Base16 in code
import base64
base64.b16encode(b"Hello").decode() # '48656C6C6F'
base64.b16decode("48656c6c6f", casefold=True) # b'Hello'
printf 'Hello' | basenc --base16 # 48656C6C6F
echo 48656C6C6F | basenc --base16 -d # Hello
basenc is part of GNU coreutils 8.31 and later. In Node.js, Buffer.from("Hello").toString("hex").toUpperCase() gives the same result. The Python and Bash pages cover the Base64 side of these modules.
FAQ
Is Base16 the same as hexadecimal?
Yes, for bytes. Base16 is the name RFC 4648 gives to hex encoding: each byte becomes two characters from 0123456789ABCDEF. The RFC specifies uppercase; everyday hex is often lowercase.
How much bigger is Base16 than the original data?
Exactly twice as big, a 100% overhead. Base32 adds 60% and Base64 about 33%, so Base16 is the least compact of the RFC 4648 encodings and the easiest to read.
Why does Python's b16decode reject my string?
base64.b16decode accepts only uppercase by default. Pass casefold=True for lowercase input, or use bytes.fromhex(), which takes both cases and spaces.