murmur2/
imp.rs

1use crate::hlp::*;
2
3// Mixing consts
4const M_64: u64 = 0xc6a4a7935bd1e995;
5const M_32: u32 = M_64 as u32;
6
7pub fn murmur2(data: &[u8], seed: u32, load: impl Fn([u8; 4]) -> u32) -> u32 {
8    let h = seed ^ (data.len() as u32);
9
10    let mut chunks = data.chunks_exact(4);
11    let h = (&mut chunks).fold(h, |h, k| round!(M_32, h, load(k.try_into().unwrap())));
12    let h = short_round!(M_32, h, chunks.remainder(), u32);
13
14    h.slack(13).wrapping_mul(M_32).slack(15)
15}
16
17pub fn murmur64a(data: &[u8], seed: u64, load: impl Fn([u8; 8]) -> u64) -> u64 {
18    let h = seed ^ (data.len() as u64).wrapping_mul(M_64); // Subtle Difference 1
19
20    let mut chunks = data.chunks_exact(8);
21    let h = (&mut chunks).fold(h, |h, k| {
22        // Subtle difference 2
23        (h ^ load(k.try_into().unwrap())
24            .wrapping_mul(M_64)
25            .slack(47)
26            .wrapping_mul(M_64))
27        .wrapping_mul(M_64)
28    });
29    let h = short_round!(M_64, h, chunks.remainder(), u64);
30
31    h.slack(47).wrapping_mul(M_64).slack(47)
32}
33
34pub fn murmur64b(data: &[u8], seed: u64, load: impl Fn([u8; 4]) -> u32) -> u64 {
35    let h1 = (seed as u32) ^ (data.len() as u32);
36    let h2 = (seed >> 32) as u32;
37
38    let mut chunks = data.chunks_exact(4);
39    let (h1, h2) = (&mut chunks).fold((h1, h2), |(h1, h2), k| {
40        (h2, round!(M_32, h1, load(k.try_into().unwrap())))
41    });
42    let (h1, h2) = match data.len() % 8 > 3 {
43        true => (h2, h1),
44        false => (h1, h2),
45    };
46    let h2 = short_round!(M_32, h2, chunks.remainder(), u32);
47
48    let h1 = (h1 ^ h2 >> 18).wrapping_mul(M_32);
49    let h2 = (h2 ^ h1 >> 22).wrapping_mul(M_32);
50    let h1 = (h1 ^ h2 >> 17).wrapping_mul(M_32);
51    let h2 = (h2 ^ h1 >> 19).wrapping_mul(M_32);
52
53    ((h1 as u64) << 32) | h2 as u64
54}
55
56pub fn murmur2a(data: &[u8], seed: u32, load: impl Fn([u8; 4]) -> u32) -> u32 {
57    let mut chunks = data.chunks_exact(4);
58    let h = (&mut chunks).fold(seed, |h, k| round!(M_32, h, load(k.try_into().unwrap())));
59    let t = rest!(chunks.remainder(), u32);
60
61    round!(M_32, round!(M_32, h, t), data.len() as u32)
62        .slack(13)
63        .wrapping_mul(M_32)
64        .slack(15)
65}