PHP 8.1: xxHash hash algorithms support
xxHash is an extremely fast hashing algorithm that is not designed for cryptographic purposes, but provides excellent randomness and dispersion of output, and uniqueness of to minimize collisions. Some xxHash variants in fact, are faster than the RAM throughput provided CPU cache is sufficient and fits.
PHP 8.1 adds support for xxHash algorithm in following variants:
xxh32
: 32-bit hash outputxxh64
: 64-bit hash outputxxh3
: 64-bit hash outputxxh128
: 128-bit hash output
hash('xxh32', 'php.watch'); // cb729dd1
hash('xxh64', 'php.watch'); // 9c823891d744a55e
hash('xxh3', 'php.watch'); // f406cee14d73b176
hash('xxh128', 'php.watch'); // 16c27099bd855aff3b3efe27980515ad
xxHash is a streaming hash, and can be used as such:
$context = hash_init('xxh3');
hash_update($context, 'php.');
hash_update($context, 'watch');
hash_final($context); // f406cee14d73b176
xxHash is not a cryptographic hashing algorithm. For password hashing, use
password_hash
and its friends. Furthermore, none of the xxHash variants are allowed inhash_hmac
function.
In PHP 8.1, xxHash is the fastest hashing algorithm supported in PHP.
Algorithm | PHP implementation speed (GB/s) |
---|---|
xxh3 |
15.19 |
xxh128 |
14.78 |
crc32c |
14.12 |
xxh64 |
13.32 |
murmur3f | 8.87 |
xxh32 |
7.47 |
sha2-256 |
0.25 |
sha1-160 |
0.70 |
md5-128 |
0.77 |
The results above are an excerpt from PHP Hash Algorithm Benchmarks.
xxHash Options
PHP 8.1 supports specifying algorithm-specific options with the new $options
parameter. Along with this, xxh*
hashing algorithms accept additional options:
Only one option is accepted at a time. For example, if a seed
option is specified, it cannot use a secret
option in the same hashing operation.
If both secret
and seed
options are passed, an Error will be thrown.
hash("xxh3", "php.watch", false, ["secret" => $secret, 'seed' => 43]);
xxh3: Only one of seed or secret is to be passed for initialization in ... on line ...
seed
option
All xxHash variants accept a seed
option through the third parameter ($options
) of the hash
function.
hash('xxh3', 'php.watch'); // "f406cee14d73b176"
hash("xxh3", "php.watch", false, ["seed" => 42]); // de9956536d1e9543
hash("xxh3", "php.watch", options: ["seed" => 42]); // de9956536d1e9543
The third example uses named parameters introduced in PHP 8.0.
secret
option
xxh3
and xxh128
variants of xxHash accept a secret
value in the third parameter ($options
array).
The required key must be larger than 135 bytes, and a key longer than 256 bytes will discarded with a warning emitted.
$secret = random_bytes(256);
hash("xxh3", "php.watch", false, ["secret" => $secret]);
// "a0dad59ce6341fb0"
It is important that the secret
value has a sufficient entropy. PHP built-in random_bytes
function is a cryptographically secure random-number generator.
xxh32
and xxh64
variants do not recognize a secret
option, and if passed, it will be silently ignored.
-
Passing a
secret
value smaller than 136 bytes causes an error:hash("xxh3", "php.watch", false, ["secret" => 'ab'])
xxh3: Secret length must be >= 136 bytes, ... bytes passed in ... code on line ...
-
Passing a
secret
value larger than 256 bytes makes PHP trim the value to 256 bytes with a warning:hash("xxh3", "php.watch", false, ["secret" => str_repeat('a', 257)]);
hash(): xxh3: Secret content exceeding 256 bytes discarded in ... code on line ...
Backwards Compatibility Impact
xxHash is newly added to PHP 8.1, and older PHP versions will not be able to use xxHash algorithms via hash
method.
Attempting to use xxHash algorithms in hash
function results in a ValueError
exception:
Fatal error: Uncaught ValueError: hash(): Argument #1 ($algo) must be a valid hashing algorithm in ...:...
On PHP versions prior to 8.0, a warning will be raised:
Warning: hash(): Unknown hashing algorithm: xxh3 in ... on line ...
Alternatives implementations include:
- Megasaxon/php-xxhash - A PHP extension to add
xxhash32
andxxhash64
for xxHash variants. - exussum12/xxhash - A pure-PHP implementation with FFI support. The pure-PHP implementation is ~600x slower than the native code, and the FFI implementation is only ~0.4x slower.
Related Changes
- PHP 8.1: Hash functions accept algorithm-specific
$options
- PHP 8.1: MurmurHash3 hash algorithm support