Upload a file
  1. base64hub
  2. Other bases
  3. Base16 (hex)

Base16 Encoder and Decoder (RFC 4648 Hex)

Encode text as RFC 4648 Base16, the alphabet 0–9 and A–F with two characters per byte, or decode Base16 back to text. Hello is 48656C6C6F.

Free no sign-up, no limits Local nothing uploaded RFC 4648 section 8 alphabet, uppercase Updated Oct 27, 2026
Input 0Bytes 0 BOutput 0

Processed in your browser. This page cannot send your data anywhere – how we know

How to use the Base16 encoder

  1. Type or paste text into the input. The Base16 appears in the output as you type.
  2. Charset under the input decides how characters become bytes. UTF-8 is the default.
  3. 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.
  4. 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:

InputBase16
(empty)(empty)
f66
fo666F
foo666F6F
foob666F6F62
fooba666F6F6261
foobar666F6F626172

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:

EncodingOutputLength
Base1648656C6C6F2C20776F726C6424
Base32JBSWY3DPFQQHO33SNRSA====24 (20 without padding)
Base64SGVsbG8sIHdvcmxk16

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 sha256sum and 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.