1use rand::{SeedableRng, rngs::SmallRng};
3
4#[inline]
6pub fn fnv1a64(data: &[u8]) -> u64 {
7 const OFFSET: u64 = 0xcbf29ce484222325;
8 const PRIME: u64 = 0x00000100000001B3;
9 let mut hash = OFFSET;
10 for b in data {
11 hash ^= *b as u64;
12 hash = hash.wrapping_mul(PRIME);
13 }
14 hash
15}
16
17#[inline]
18pub fn mix64(a: u64, b: u64) -> u64 {
19 let mut x = a ^ (b.rotate_left(17));
21 x ^= x >> 33;
22 x = x.wrapping_mul(0xff51afd7ed558ccd);
23 x ^= x >> 33;
24 x = x.wrapping_mul(0xc4ceb9fe1a85ec53);
25 x ^ (x >> 33)
26}
27
28pub fn compose_seed(
31 workbook_seed: u64,
32 sheet_id: u32,
33 row: u32,
34 col: u32,
35 fn_salt: u64,
36 recalc_epoch: u64,
37) -> (u64, u64) {
38 let pos = ((sheet_id as u64) << 40) ^ ((row as u64) << 20) ^ (col as u64);
39 let lane0 = mix64(workbook_seed ^ fn_salt ^ recalc_epoch, pos);
41 let lane1 = mix64(recalc_epoch ^ 0xA5A5_A5A5_5A5A_5A5A_u64, pos.rotate_left(7));
42 (lane0, lane1)
43}
44
45pub fn small_rng_from_lanes(l0: u64, l1: u64) -> SmallRng {
47 let s = mix64(l0, l1);
49 SmallRng::seed_from_u64(s)
50}