Rust port of N-R-K/ChibiHash. See the article ChibiHash: A small, fast 64-bit hash function for more information.
All credit for the algorithm goes to N-R-K.
- 64-bit hash function
- Deterministic
- Fast
- No dependencies
no-std
compatible- Multiple ways to use ChibiHash:
- Direct Hashing: One-shot hashing using
chibi_hash64()
- Simple Hasher: Basic implementation using
ChibiHasher
(implementsstd::hash::Hasher
) - Streaming Hasher: Memory-efficient streaming with
StreamingChibiHasher
(implementsstd::hash::Hasher
) - BuildHasher:
ChibiHasher
implementsBuildHasher
. This allows using ChibiHash as the default hasher forstd::collections::HashMap
andstd::collections::HashSet
. UseChibiHashMap
andChibiHashSet
types.
- Direct Hashing: One-shot hashing using
use chibihash::{chibi_hash64, ChibiHasher, StreamingChibiHasher, ChibiHashMap, ChibiHashSet};
use std::hash::Hasher;
fn main() {
// Method 1: Direct hashing
let hash = chibi_hash64(b"yellow world", 42);
println!("Direct hash: {:016x}", hash);
// Method 2: Using Hasher trait
let mut hasher = ChibiHasher::new(42);
hasher.write(b"yellow world");
println!("Hasher trait: {:016x}", hasher.finish());
// Method 3: Streaming hashing
let mut hasher = StreamingChibiHasher::new(0);
hasher.update(b"yellow ");
hasher.update(b"world");
println!("Streaming: {:016x}", hasher.finalize());
// Method 4: BuildHasher for HashMap
let mut map: ChibiHashMap<String, i32> = ChibiHashMap::default();
map.insert("hello".to_string(), 42);
println!("BuildHasher HashMap: {:?}", map.get("hello"));
// Method 5: BuildHasher for HashSet
let mut set: ChibiHashSet<String> = ChibiHashSet::default();
set.insert("hello".to_string());
println!("BuildHasher HashSet: {}", set.contains("hello"));
}
Run cargo test
to see the tests.
Run cargo bench
to see the benchmarks. See target/criterion/report/index.html
for the HTML report.
The repository also contains a benchmark comparing the Rust implementation to the C implementation. Run cargo bench --features ffi
to see the benchmark. The C version can be found from the csrc
directory. The benchmark utilises FFI to call the C version.
Based on limited testing, the pure Rust implementation is faster than the C version when the input sizes are small (below 1024 bytes). With larger input sizes they are equal. Possibly due to the overhead of the FFI interface itself.
Copy-paste from the original repository. Same applies here.
Here are some reasons to avoid using this:
- For cryptographic purposes.
- For protecting against collision attacks (SipHash is the recommended one for this purpose).
- When you need very strong probability against collisions: ChibiHash does very minimal amount of mixing compared to other hashes (e.g xxhash64). And so chances of collision should in theory be higher.
MIT. The original C version is under the Unlicense.