fnv1a-pure
Zero-dependency pure-stdlib FNV-1a and FNV-1 hash (32/64-bit) for Python.
fnv1a-pure provides Fowler-Noll-Vo FNV-1a and FNV-1 hash functions without any C extensions or third-party dependencies. Works on CPython 3.8+, MicroPython, and Pyodide.
Quick Start
pip install -e .
from fnv1a_pure import fnv1a_64, fnv1a_32, fnv1_64, fnv1_32, fnv1a_64_hex, fnv1a_32_hex
# FNV-1a-64 (most common variant)
fnv1a_64(b"hello") # → 11831194018420276491
fnv1a_64_hex(b"hello") # → "a430d84680aabd0b"
# FNV-1a-32
fnv1a_32(b"hello") # → 1335831723
fnv1a_32_hex(b"hello") # → "4f9f2cab"
# FNV-1 (alternate: multiply-before-XOR)
fnv1_64(b"hello") # → 8883723591023973575 (different from FNV-1a)
fnv1_32(b"hello") # → 3233227887
Why fnv1a-pure?
- Zero dependencies — pure stdlib, no C extensions, no
pip installfailures on Pyodide/WebAssembly - Works everywhere — CPython 3.8+, MicroPython, Pyodide, AWS Lambda, serverless environments
- Canonical algorithm — FNV-1a is the de-facto standard non-cryptographic hash in Memcached, Redis, Nginx, and Cloudflare's load balancers
- Small footprint — single file, ~85 LOC core, no bloat
Competitor: fnvhash (PyPI) is a C extension requiring compilation — fails on Pyodide and zero-compile serverless.
Key Features
fnv1a_64(data: bytes) -> int— FNV-1a-64 hash, unsigned 64-bitfnv1a_32(data: bytes) -> int— FNV-1a-32 hash, unsigned 32-bitfnv1_64(data: bytes) -> int— FNV-1-64 hash (multiply-before-XOR variant)fnv1_32(data: bytes) -> int— FNV-1-32 hashfnv1a_64_hex(data: bytes) -> str— zero-padded 16-char hex stringfnv1a_32_hex(data: bytes) -> str— zero-padded 8-char hex string
API Reference
All functions accept bytes and return an unsigned int:
| Function | Input | Output |
|---|---|---|
fnv1a_64(b"hello") |
bytes | unsigned 64-bit int |
fnv1a_32(b"hello") |
bytes | unsigned 32-bit int |
fnv1_64(b"hello") |
bytes | unsigned 64-bit int |
fnv1_32(b"hello") |
bytes | unsigned 32-bit int |
fnv1a_64_hex(b"hello") |
bytes | 16-char hex str |
fnv1a_32_hex(b"hello") |
bytes | 8-char hex str |
Test Vectors
| Input | FNV-1a-64 | FNV-1a-32 |
|---|---|---|
b"" |
14695981039346656037 | 2166136261 |
b"a" |
12638187200555641996 | 3826002220 |
b"hello" |
11831194018420276491 | 1335831723 |
b"hello world" |
8618312879776256743 | 3582672807 |
All values verified against the FNV reference implementation (first principles).
Limitations
This is NOT a cryptographic hash. FNV-1a is a non-cryptographic hash designed for hash tables and bloom filters — not for security purposes. It is intentionally fast and simple, not collision-resistant or preimage-resistant. Do not use it for password hashing, digital signatures, or any security-critical purpose.
Byte strings only — pass data.encode() for string input. Passing str directly raises TypeError.
Test Suite
111 tests covering:
- All 10 acceptance criteria (each has ≥1 test)
- Canonical test vectors from FNV reference
- Determinism: identical input always produces identical output
- Byte-order independence
- Edge cases: empty input, all-zeros, all-ones, 64KB payloads
- FNV-1 vs FNV-1a distinction
- Property: distinct inputs produce distinct outputs
- All 256 single-byte values, collision-free in 64-bit space
pytest -q
Acceptance Criteria Checklist
| # | Criterion | Status |
|---|---|---|
| 1 | fnv1a_64(b"") returns 14695981039346656037 |
✓ |
| 2 | fnv1a_64(b"hello") returns canonical value |
✓ |
| 3 | fnv1a_32(b"hello") returns canonical value |
✓ |
| 4 | fnv1a_64_hex(b"hello") returns 16-char zero-padded hex |
✓ |
| 5 | FNV-1 and FNV-1a produce different hashes | ✓ |
| 6 | All functions return unsigned integers | ✓ |
| 7 | Byte-order independent (deterministic) | ✓ |
| 8 | Repeating bytes "a", "aa", … produce distinct values |
✓ |
| 9 | ≥100 collected tests with ≥1 per AC | ✓ (111 tests) |
| 10 | No external imports beyond Python stdlib | ✓ |
References
- FNV Hash — Wikipedia (HTTP 200 verified)
- IETF draft-eastlake-fnv (historical reference) (HTTP 200 verified)
- FNV source repository — Landon Curt Noll (HTTP 200 verified)
License
MIT License — see LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fnv1a_pure-0.1.0.tar.gz.
File metadata
- Download URL: fnv1a_pure-0.1.0.tar.gz
- Upload date:
- Size: 8.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fc2d91122339014eb304e0d398d07d170f31efb091ec1e90dbc2eb524facba31
|
|
| MD5 |
04512053787380c41575ad7a8b64b559
|
|
| BLAKE2b-256 |
a4da7180df345819dc53d033050af0a24a1b4fc56cc7e5bf75679c6f3c3237b1
|
File details
Details for the file fnv1a_pure-0.1.0-py3-none-any.whl.
File metadata
- Download URL: fnv1a_pure-0.1.0-py3-none-any.whl
- Upload date:
- Size: 4.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa08273570f052bdac544be43206aa10b3d5c39b47f5c912700d8e2e8c6803b1
|
|
| MD5 |
feee9a704429223d07fc7fe3d91d1e9d
|
|
| BLAKE2b-256 |
c33a2e5af791dd9924d20728f853d620b7f624493a4527f1f9c03e6f1dbc9c12
|