rapidhash_u128/
lib.rs

1const SEED: u64 = 0xbdd8_9aa9_8270_4029;
2const MAGIC: [u64; 3] = [
3    0x2d35_8dcc_aa6c_78a5,
4    0x8bb8_4b93_962e_acc9,
5    0x4b33_a62e_d433_d4a3,
6];
7const MAGICSEED: u64 = SEED ^ mix(SEED ^ MAGIC[0], MAGIC[1]) ^ 16;
8
9#[inline(always)]
10const fn mum(a: u64, b: u64) -> (u64, u64) {
11    let r = a as u128 * b as u128;
12    let a1 = (r & 0x00000000_00000000_ffffffff_ffffffff) as u64;
13    let b1 = (r >> 64) as u64;
14    return (a1, b1);
15}
16
17#[inline(always)]
18const fn mix(a: u64, b: u64) -> u64 {
19    let (a1, b1) = mum(a, b);
20    return a1 ^ b1;
21}
22
23pub fn hash(key: u128) -> u64 {
24    // println!("{:?}", key.to_le_bytes());
25    let w3 = (key >> 96) as u32;
26    let w2 = ((key & 0x00000000_ffffffff_00000000_00000000) >> 64) as u32;
27    let w1 = ((key & 0x00000000_00000000_ffffffff_00000000) >> 32) as u32;
28    let w0 = (key & 0x00000000_00000000_00000000_ffffffff) as u32;
29    let mut a = (w0 as u64) << 32 | w3 as u64;
30    let mut b = (w1 as u64) << 32 | w2 as u64;
31    (a, b) = mum(a ^ MAGIC[1], b ^ MAGICSEED);
32    return mix(a ^ MAGIC[0] ^ 16, b ^ MAGIC[1]);
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38
39    #[test]
40    fn it_hashes_as_expected() {
41        assert_eq!(                                    hash(0),  8755926293314635566);
42        assert_eq!(                                    hash(1), 17996969877019643443);
43        assert_eq!(                                 hash(0xff),  5200326291411116507);
44        assert_eq!(                               hash(0x1000),  3752997491443908878);
45        assert_eq!(                          hash(0x1000_0000),  1347028408682550078);
46        assert_eq!(                  hash(0x10000000_00000000),  3593052489046108800);
47        assert_eq!(                  hash(0x10000000_00000001),  7365235785575411947);
48        assert_eq!(         hash(0x10000000_00000000_00000000),  5399386355486589714);
49        assert_eq!(hash(0x10000000_00000000_00000000_00000000), 13365378750111633005);
50        assert_eq!(hash(0xffffffff_ffffffff_ffffffff_ffffffff), 10466158564987642889);
51    }
52}