use std::hash::{BuildHasher, Hasher};
pub fn hash_string_masked(s: &str, bound: u64) -> u64 {
let mut h = std::collections::hash_map::RandomState::new().build_hasher();
h.write(s.as_bytes());
if bound == 0 { 0 } else { h.finish() & bound }
}
pub fn hash_string_modulo(s: &str, modulus: u64) -> u64 {
let mut h = std::collections::hash_map::RandomState::new().build_hasher();
h.write(s.as_bytes());
if modulus <= 1 {
0
} else {
h.finish() % modulus
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn masked_hash_within_bound() {
let bound = 0xFFu64;
for i in 0..32 {
let s = format!("k{i}");
assert!(hash_string_masked(&s, bound) <= bound);
}
}
#[test]
fn modulo_hash_within_modulus() {
let m = 7u64;
for i in 0..32 {
let s = format!("k{i}");
assert!(hash_string_modulo(&s, m) < m);
}
}
#[test]
fn zero_modulus_returns_zero() {
assert_eq!(hash_string_modulo("x", 0), 0);
assert_eq!(hash_string_modulo("x", 1), 0);
}
}