xxhash is a Python binding for the xxHash library by Yann Collet.
$ pip install xxhash
On Debian/Ubuntu:
$ apt-get install python-dev gcc
On CentOS/Fedora:
$ yum install python-devel gcc redhat-rpm-config
Module version and its backend xxHash library version can be retrieved using
the module properties VERSION
AND XXHASH_VERSION
respectively.
>>> import xxhash
>>> xxhash.VERSION
'1.2.0'
>>> xxhash.XXHASH_VERSION
'0.6.5'
This module is hashlib-compliant, which means you can use it in the same way as hashlib.md5
.
update() -- update the current digest with an additional stringdigest() -- return the current digest valuehexdigest() -- return the current digest as a string of hexadecimal digitsintdigest() -- return the current digest as an integercopy() -- return a copy of the current xxhash objectreset() -- reset state
md5 digest returns bytes, but the original xxh32 and xxh64 C APIs return integers.
While this module is made hashlib-compliant, intdigest()
is also provided to
get the integer digest.
Constructors for hash algorithms provided by this module are xxh32()
and xxh64()
.
For example, to obtain the digest of the byte string b'Nobody inspects the spammish repetition'
.
>>> import xxhash
>>> x = xxhash.xxh32()
>>> x.update(b'Nobody inspects')
>>> x.update(b' the spammish repetition')
>>> x.digest()
b'\xe2);/'
>>> x.digest_size
4
>>> x.block_size
16
More condensed.
>>> xxhash.xxh32(b'Nobody inspects the spammish repetition').hexdigest()
'e2293b2f'
>>> xxhash.xxh32(b'Nobody inspects the spammish repetition').digest() == x.digest()
True
An optional seed (default is 0) can be used to alter the result predictably.
>>> import xxhash
>>> xxhash.xxh64('xxhash').hexdigest()
'32dd38952c4bc720'
>>> xxhash.xxh64('xxhash', seed=20141025).hexdigest()
'b559b98d844e0635'
>>> x = xxhash.xxh64(seed=20141025)
>>> x.update('xxhash')
>>> x.hexdigest()
'b559b98d844e0635'
>>> x.intdigest()
13067679811253438005
Be careful that xxh32 takes an unsigned 32-bit integer as seed, while xxh64 takes an unsigned 64-bit integer. Although unsigned integer overflow is defined behavior, it's better to not to let it happen.
>>> xxhash.xxh32('I want an unsigned 32-bit seed!', seed=0).hexdigest()
'f7a35af8'
>>> xxhash.xxh32('I want an unsigned 32-bit seed!', seed=2**32).hexdigest()
'f7a35af8'
>>> xxhash.xxh32('I want an unsigned 32-bit seed!', seed=1).hexdigest()
'd8d4b4ba'
>>> xxhash.xxh32('I want an unsigned 32-bit seed!', seed=2**32+1).hexdigest()
'd8d4b4ba'
>>>
>>> xxhash.xxh64('I want an unsigned 64-bit seed!', seed=0).hexdigest()
'd4cb0a70a2b8c7c1'
>>> xxhash.xxh64('I want an unsigned 64-bit seed!', seed=2**64).hexdigest()
'd4cb0a70a2b8c7c1'
>>> xxhash.xxh64('I want an unsigned 64-bit seed!', seed=1).hexdigest()
'ce5087f12470d961'
>>> xxhash.xxh64('I want an unsigned 64-bit seed!', seed=2**64+1).hexdigest()
'ce5087f12470d961'
digest()
returns bytes of the big-endian representation of the integer
digest.
>>> import xxhash
>>> h = xxhash.xxh64()
>>> h.digest()
b'\xefF\xdb7Q\xd8\xe9\x99'
>>> h.intdigest().to_bytes(8, 'big')
b'\xefF\xdb7Q\xd8\xe9\x99'
>>> h.hexdigest()
'ef46db3751d8e999'
>>> format(h.intdigest(), '016x')
'ef46db3751d8e999'
>>> h.intdigest()
17241709254077376921
>>> int(h.hexdigest(), 16)
17241709254077376921
Besides xxh32/xxh64 mentioned above, oneshot functions are also provided. By using oneshot functions we can avoid creating XXH32/64_state on heap.
xxh32_digest(bytes, seed)xxh32_intdigest(bytes, seed)xxh32_hexdigest(bytes, seed)xxh64_digest(bytes, seed)xxh64_intdigest(bytes, seed)xxh64_hexdigest(bytes, seed)
>>> import xxhash
>>> xxhash.xxh64('a').digest == xxhash.xxh64_digest('a')
False
>>> xxhash.xxh64('a').digest() == xxhash.xxh64_digest('a')
True
>>> xxhash.xxh64('a').intdigest() == xxhash.xxh64_intdigest('a')
True
>>> xxhash.xxh64('a').hexdigest() == xxhash.xxh64_hexdigest('a')
True
>>> xxhash.xxh64_hexdigest('xxhash', seed=20141025)
'b559b98d844e0635'
>>> xxhash.xxh64_intdigest('xxhash', seed=20141025)
13067679811253438005L
>>> xxhash.xxh64_digest('xxhash', seed=20141025)
'\xb5Y\xb9\x8d\x84N\x065'
xxh32 takes an unsigned 32-bit integer as seed, and xxh64 takes
an unsigned 64-bit integer as seed. Make sure that the seed is greater than
or equal to 0
.
As of python-xxhash 0.3.0, digest()
returns bytes of the
big-endian representation of the integer digest. It used
to be little-endian.
Though you can use xxhash as an HMAC hash function, but it's highly recommended not to.
xxhash is NOT a cryptographic hash function, it is a non-cryptographic hash algorithm aimed at speed and quality. Do not put xxhash in any position where cryptographic hash functions are required.
Copyright (c) 2014-2018 Yue Du - https://github.com/ifduyue
Licensed under BSD 2-Clause License
- Add oneshot functions xxh{32,64}_{,int,hex}digest
- Allow input larger than 2GB
- Release the GIL on sufficiently large input
- Drop support for Python 3.2
- Free state actively, instead of delegating it to ffi.gc
- Fixed copy() segfault
- Added CFFI variant
- Fixed copy() segfault
- Upgrade xxHash to v0.6.2
- Upgrade xxHash to v0.6.1
- Upgrade xxHash to v0.5.0
- Upgrade xxHash to r42
- Upgrade xxHash to r41
- Added method reset
- Upgrade xxHash to r40
- Fixed some typos in docstrings
- Upgrade xxHash to r39
- Change digest() from little-endian representation to big-endian representation of the integer digest. This change breaks compatibility (digest() results are different).
- Make this package hashlib-compliant
- Update xxHash to r37
- Improve: Check XXHnn_init() return value.
- Update xxHash to r36
- Improve: Can now be built with Visual C++ Compiler.
- New: XXH32 and XXH64 type, which support partially update.
- Fix: build under Python 3.4
- NEW: Support Python 3
- NEW: xxh32 and xxh64