https://github.com/jlumbroso/python-random-hash
A simple, time-tested, family of random hash functions in Python, based on CRC32 and xxHash, affine transformations, and the Mersenne Twister. 🎲
https://github.com/jlumbroso/python-random-hash
analysis-of-algorithms analytic-combinatorics data-streaming flajolet flajolet-martin hash-functions hyperloglog python randomized-algorithm streaming-algorithms
Last synced: 2 months ago
JSON representation
A simple, time-tested, family of random hash functions in Python, based on CRC32 and xxHash, affine transformations, and the Mersenne Twister. 🎲
- Host: GitHub
- URL: https://github.com/jlumbroso/python-random-hash
- Owner: jlumbroso
- License: lgpl-3.0
- Created: 2022-05-31T01:52:53.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2022-06-06T05:44:49.000Z (over 3 years ago)
- Last Synced: 2024-11-28T22:11:37.697Z (10 months ago)
- Topics: analysis-of-algorithms, analytic-combinatorics, data-streaming, flajolet, flajolet-martin, hash-functions, hyperloglog, python, randomized-algorithm, streaming-algorithms
- Language: Python
- Homepage: https://pypi.org/project/randomhash/
- Size: 32.2 KB
- Stars: 9
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Python `randomhash` package
[](https://github.com/jlumbroso/python-random-hash/actions/workflows/continuous-integration.yaml)
[](https://codecov.io/gh/jlumbroso/python-random-hash)A simple, time-tested, family of random hash functions in Python, based on CRC32
and xxHash, affine transformations, and the Mersenne Twister.This is a companion library to [the identical Java version](https://github.com/jlumbroso/java-random-hash).
## Installation and usage
The library is available on PyPI, and can be installed through normal means:
```shell
$ pip install randomhash
```Once installed, it can be called either by instantiating a family of random
hash functions, or using the default instantiated functions:```python
import randomhash# Create a family of random hash functions, with 10 hash functions
rfh = randomhash.RandomHashFamily(count=10)
print(rfh.hashes("hello")) # will compute the ten hashes for "hello"# Use the default instantiated functions
print(randomhash.hashes("hello", count=10))
```## Features
This introduces a family of hash functions that can be used to implement probabilistic
algorithms such as HyperLogLog. It is based on _affine transformations of either the
CRC32 hash functions_, which have been empirically shown to provide good performance
(for consistency with other versions of this library, such as the Java version), or
[the more complex xxHash hash functions](https://cyan4973.github.io/xxHash/) that are
made available through [the `xxhash` Python bindings](https://github.com/ifduyue/python-xxhash).
The pseudo-random numbers are drawn according to
[the standard Python implementation](https://docs.python.org/3/library/random.html)
of the [Mersenne Twister](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html).## Some history
In 1983, G. N. N. Martin and Philippe Flajolet introduced the algorithm known
as [_Probabilistic Counting_](http://algo.inria.fr/flajolet/Publications/FlMa85.pdf),
designed to provide an extremely accurate and efficient
estimate of the number of unique words from a document that may contain repetitions.
This was an incredibly important algorithm, which introduced a **revolutionary idea**
at the time:> The only assumption made is that records can be hashed in a suitably pseudo-uniform
> manner. This does not however appear to be a severe limitation since empirical
> studies on large industrial files [5] reveal that _careful_ implementations of
> standard hashing techniques do achieve practically uniformity of hashed values.The idea is that hash functions can "transform" data into pseudo-random variables.
Then a text can be treated as a sequence of random variables drawn from a uniform
distribution, where a given word will always occur as the same random value (i.e.,
`a b c a a b c` could be hashed as `.00889 .31423 .70893 .00889 .00889 .31423 .70893` with
every occurrence of `a` hashing to the same value). While this sounds strange,
empirical evidence suggests it is true enough in practice, and eventually [some
theoretical basis](https://people.seas.harvard.edu/~salil/research/streamhash-Jun10.pdf)
has come to support the practice.The original _Probabilistic Counting_ (1983) algorithm gave way to _LogLog_ (2004),
and then eventually _HyperLogLog_ (2007), one of the most famous algorithms in the
world as described in [this article](https://arxiv.org/abs/1805.00612). These algorithms
and others all used the same idea of hashing inputs to treat them as random variables,
and proved remarkably efficient and accurate.But as highlighted in the above passage, it is important to be _careful_.
## Hash functions in practice
In practice, it is easy to use poor quality hash functions, or to use cryptographic
functions which will significantly slow down the speed (and relevance) of the
probabilistic estimates. However, on most data, some the cyclic polynomial checksums
(such as Adler32 or CRC32) provide good results---as do efficient, general-purpose
non-cryptographic hash functions such as xxHash.