Base16 (hex) encoder / decoder
Encode text to hexadecimal bytes or decode hex back to text using RFC 4648 §8.
Docify's Base16 encoder (also called hex or hexadecimal) implements RFC 4648 §8 using the 0-9 A-F alphabet. Each byte becomes two hex characters. Example: foobar encodes to 666F6F626172. No padding is used. Decoding is case-insensitive and accepts whitespace between digit pairs. This is not integer conversion (use Number Base Converter) or CSS colors (use Color Converter). Nothing is uploaded.
How it works
- Encoding: Input text is converted to UTF-8 bytes. Each byte is represented as two hexadecimal digits (00-FF). Output is always uppercase.
- Decoding: Hex digits are parsed in pairs and converted back to bytes, then decoded as UTF-8. Whitespace between pairs is ignored. Case is insensitive.
- No padding: Unlike Base64 and Base32, hex encoding requires no padding because each byte maps to exactly two characters.
- Efficiency: Hex is 50% efficient (2 characters per byte) vs Base64 at 75% (4 characters per 3 bytes). Use hex for debugging and readability, Base64 for compactness.
Encoding efficiency comparison
| Encoding | Characters / byte | Efficiency |
|---|---|---|
| Base16 (hex) | 2 | 50% |
| Base32 | 1.6 | 62.5% |
| Base64 | 1.33 | 75% |
Base16 in Python and Node
The snippets below encode UTF-8 bytes as RFC 4648 §8 hexadecimal (two digits per octet, no padding). That is the same Base16 this page returns for text. Node 'hex' and CPython bytes.hex() write lowercase; this page writes uppercase 0–9 A–F, so the snippets call toUpperCase() / upper(). They are not integer conversion (hex(255) is '0xff') and not CSS color hex. For how hex compares to Base64 and Base32, see Hex vs Base64 vs Base32: RFC 4648 Encodings.
Node.js with Buffer
Node's Buffer encoding 'hex' is RFC 4648 §8 in lowercase. Pass 'utf8' so the bytes match this page's encodeURIComponent path, then upper-case the string. Decode accepts both cases:
const encoded = Buffer.from('foobar', 'utf8').toString('hex').toUpperCase();
// "666F6F626172"
const decoded = Buffer.from(encoded, 'hex').toString('utf8');
// "foobar"Python with bytes.hex
bytes.hex() is lowercase; call .upper() to match this page. Encode UTF-8 first — a str has no hex() that returns RFC 4648 octets. bytes.fromhex accepts both cases and spaces between pairs:
encoded = 'foobar'.encode('utf-8').hex().upper()
# '666F6F626172'
decoded = bytes.fromhex(encoded).decode('utf-8')
# 'foobar'Odd-length hex is rejected here and by bytes.fromhex; Node 'hex' drops the last nibble (666 decodes as f). This page strips all whitespace, then reads pairs; bytes.fromhex allows spaces between complete pairs; Node 'hex' stops at the first non-hex character, so 66 6F is only f. binascii.hexlify is the same lowercase encode; unhexlify rejects spaces. Integer hex(255) belongs on the Number Base Converter; CSS #3366cc belongs on the Color Converter.
Base16 in the shell
Text encode on this page converts UTF-8 bytes to RFC 4648 §8 hexadecimal (two digits per octet, 0–9 A–F) with no spaces, wrap, or padding. GNU coreutils 8.31+ basenc --base16 writes that same uppercase alphabet. It wraps at 76 characters by default; pass -w 0 to match this page. echo appends a newline, so use printf to match this page's encoding of foobar. macOS ships neither basenc nor base32. Homebrew coreutils installs gbasenc. OpenSSL has openssl base64, not a Base16 encoder. basenc --base32 is RFC 4648 §6 and --base32hex is §7 — those belong on Base32 and Base32hex. There is no POSIX Base16 encoder that writes a continuous uppercase stream. hexdump and xxd samples stay below. These commands encode octets, not integer hex(255) or CSS color hex.
GNU basenc (Linux)
Coreutils basenc --base16 reads a file or stdin. Decode with -d. GNU -i means --ignore-garbage on decode — it is not an input-file flag:
# Text without a trailing newline (same as this page) printf 'foobar' | basenc --base16 -w 0 # 666F6F626172 printf '666F6F626172' | basenc --base16 -d # foobar
Default GNU decode is stricter than this page. Lowercase letters fail with basenc: invalid input — this decoder always accepts both cases. -i skips lowercase as garbage; it does not casefold, so 666f6f626172 with -i decodes as ffbar (the f digits are dropped). Spaces between pairs also need -i; this page strips all whitespace. Newlines in the encoded stream are allowed. Odd-length hex writes the complete octets, then errors on the dangling nibble (666 prints f and exits 1). This page rejects odd length before decoding. Empty stdin encodes to empty; this page asks for text. For hexdump and xxd, see the blocks below. For Python or Node on macOS or Windows, use the snippets above.
hexdump (util-linux / BSD)
hexdump -C is a hex+ASCII dump with offsets — not RFC 4648 Base16. The format string below writes one continuous uppercase stream. There is no decode flag; use xxd -r -p or the Python block above:
# Text without a trailing newline (same as this page) printf 'foobar' | hexdump -ve '1/1 "%02X"' # 666F6F626172
xxd -p (vim)
Plain -p / -ps hex is lowercase. Default wrap is 30 octets; -c 0 is a single line on vim 8.2.4088+ (older xxd, including many macOS builds, caps -c at 256). Decode with -r -p:
printf 'foobar' | xxd -p -u # 666F6F626172 printf '666F6F626172' | xxd -r -p # foobar
POSIX od -An -tx1 writes space-separated lowercase bytes and a leading space ( 66 6f 6f 62 61 72). Repeated lines become * unless you pass -v. Default xxd (no -p) and Windows certutil -encodehex are offset dumps, not this page's stream. xxd -r -p skips garbage; this page rejects non-hex after stripping whitespace. Odd-length hex is rejected here. Integer hex belongs on the Number Base Converter; CSS colors belong on the Color Converter.
FAQ
- Does this tool upload my text?
- No. All encoding and decoding runs in your browser using JavaScript. Nothing is sent to a server.
- What is Base16 / hexadecimal encoding?
- Base16 represents each byte as two hexadecimal characters (0-9 A-F). It is the most verbose base encoding but the easiest to read and debug. Also called "hex encoding."
- Is Base16 decoding case-sensitive?
- No. This decoder accepts both uppercase and lowercase hex digits. 666F6F626172 and 666f6f626172 decode to the same result.
- Does Base16 use padding like Base64?
- No. Base16 has no padding because each byte maps exactly to two characters. The encoded length is always exactly twice the input byte length.
- Is this the same as integer hex conversion?
- No. This tool encodes/decodes UTF-8 byte sequences. To convert integers between decimal and hex (e.g., 255 ↔ FF), use our Number Base Converter tool.
- Is this the same as CSS color hex codes?
- No. CSS hex colors (#3366cc) represent RGB values in a specific format. This tool encodes arbitrary text as hex bytes. Use our Color Converter for CSS colors.