pub fn seeded_hash(seed: u64, s: &str) -> u64 {
let mut h = blake3::Hasher::new();
for part in [&seed.to_le_bytes()[..], s.as_bytes()] {
h.update(&(part.len() as u64).to_le_bytes());
h.update(part);
}
u64::from_le_bytes(h.finalize().as_bytes()[..8].try_into().unwrap())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn same_seed_and_input_are_deterministic() {
assert_eq!(seeded_hash(42, "abc"), seeded_hash(42, "abc"));
}
#[test]
fn different_seeds_spread_the_same_input() {
assert_ne!(seeded_hash(1, "abc"), seeded_hash(2, "abc"));
}
#[test]
fn different_inputs_spread_the_same_seed() {
assert_ne!(seeded_hash(1, "ab"), seeded_hash(1, "ab_extra"));
}
#[test]
fn seeded_hash_is_a_stable_golden_value() {
assert_eq!(seeded_hash(7, "startpos"), 13402537162744184401);
}
}