1use rand::SeedableRng;
2use rand_chacha::ChaCha8Rng;
3
4pub fn derive_seed(master: u64, index: usize) -> u64 {
10 let combined = master
13 .wrapping_add(index as u64)
14 .wrapping_mul(0x9E3779B97F4A7C15);
15 let mut rng = ChaCha8Rng::seed_from_u64(combined);
16 rand::Rng::random::<u64>(&mut rng)
17}
18
19pub fn rng_from_seed(seed: u64) -> ChaCha8Rng {
21 ChaCha8Rng::seed_from_u64(seed)
22}
23
24#[cfg(test)]
25mod tests {
26 use super::*;
27
28 #[test]
29 fn derive_seed_is_deterministic() {
30 let s1 = derive_seed(42, 0);
31 let s2 = derive_seed(42, 0);
32 assert_eq!(s1, s2);
33 }
34
35 #[test]
36 fn derive_seed_differs_by_index() {
37 let s0 = derive_seed(42, 0);
38 let s1 = derive_seed(42, 1);
39 let s2 = derive_seed(42, 2);
40 assert_ne!(s0, s1);
41 assert_ne!(s1, s2);
42 assert_ne!(s0, s2);
43 }
44
45 #[test]
46 fn derive_seed_differs_by_master() {
47 let s1 = derive_seed(1, 0);
48 let s2 = derive_seed(2, 0);
49 assert_ne!(s1, s2);
50 }
51}