hex2bin
Decodes a hexadecimal string back into the binary data it represents, two characters per byte.
hex2bin(string $string): string|false- Added in PHP 5.4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$string | string | Hexadecimal representation of data. Must have an even length and contain only the characters 0-9, a-f and A-F. |
Return value
string|falseThe binary representation of the given hexadecimal data, or false on failure.
Errors
Emits an E_WARNING and returns false if the input has an odd length or contains a character that is not a hexadecimal digit.
hex2bin reverses bin2hex: every pair of hex digits becomes one byte. Input case does not matter, so ff and FF both decode to the byte 0xFF. The result is exactly half the length of the input.
When to reach for it
Use it whenever binary data has been travelling as printable hex — a token stored in a database column, a raw hash pulled out of a log, an encryption key or IV supplied in a config file, or bytes carried through a URL. Pair it with hash_equals when comparing decoded digests.
What trips people up
It does not convert a hexadecimal number into a decimal or binary one. hex2bin("ff") gives one raw byte, not the string 255 or 11111111. For numeric conversion use hexdec or base_convert.
Failure is quiet by modern standards: an odd-length or non-hex input emits an E_WARNING and returns false rather than throwing. Because false silently becomes "" in a string context, always validate first with ctype_xdigit and an even-length check, or test the return value with ===.
The output is raw bytes, so echoing it to a terminal or a web page usually produces garbage — that is expected, not a bug.
Example
When to use it
- Decode a hex-encoded API token or session ID back to raw bytes before an HMAC comparison.
- Rebuild a binary encryption key or IV that was stored as hex in a config file or environment record.
- Turn a hex digest copied from a log line back into raw bytes for a byte-by-byte comparison.
Frequently asked questions
Why does hex2bin return false?
Because the input has an odd number of characters or contains something outside 0-9a-fA-F. Validate with ctype_xdigit and an even-length check before calling it.
What is the difference between hex2bin and hexdec?
hex2bin decodes pairs of hex digits into raw bytes, while hexdec converts a hex string into an integer. hex2bin("ff") is one byte; hexdec("ff") is the number 255.
Does hex2bin care about uppercase hex?
No, uppercase and lowercase digits decode identically. Only the length and the character set matter.
More examples
Round-tripping a token
Eight random bytes render as 16 hex characters. Decoding gives the original 8 bytes back, and re-encoding reproduces the exact same token string, confirming the round trip is lossless.
<?php
$token = bin2hex(random_bytes(8));
echo strlen($token), " hex chars\n";
$raw = hex2bin($token);
var_dump(strlen($raw));
var_dump(bin2hex($raw) === $token);Not a number converter
hex2bin("ff") produces one raw byte whose ordinal value is 255. If you actually wanted the number, hexdec gives 255 and base_convert gives the binary digits 11111111 — three different results from the same input.
<?php
$byte = hex2bin("ff");
echo strlen($byte), "\n";
echo ord($byte), "\n";
echo hexdec("ff"), "\n";
echo base_convert("ff", 16, 2), "\n";Validating before decoding
Only the first string passes the even-length and ctype_xdigit checks and decodes to 4 bytes. The odd-length, non-hex and empty inputs are rejected before hex2bin is ever called, so no warning is emitted and no false leaks into later code.
<?php
$inputs = ["deadbeef", "abc", "zz", ""];
foreach ($inputs as $in) {
$ok = $in !== "" && strlen($in) % 2 === 0 && ctype_xdigit($in);
echo str_pad(var_export($in, true), 12);
echo $ok ? "-> " . strlen(hex2bin($in)) . " bytes\n" : "-> rejected\n";
}
Discussion