1#![no_std]
2
3#[cfg(test)]
4mod tests {
5 use super::murmur3_32;
6 #[test]
7 fn standard_murmur3_32() {
8 assert_eq!(murmur3_32(&[], 0), 0);
9 assert_eq!(murmur3_32(&[], 1), 0x514E28B7);
10 assert_eq!(murmur3_32(&[], 0xffffffff), 0x81F16F39);
11 assert_eq!(murmur3_32(&[0, 0, 0, 0], 0), 0x2362F9DE);
12 assert_eq!(murmur3_32(&[0x74, 0x61, 0x72, 0x69], 0), 0x78ab8db9);
13 assert_eq!(
14 murmur3_32(&[0x21, 0x43, 0x65, 0x87], 0x5082EDEE),
15 0x2362F9DE
16 );
17 assert_eq!(murmur3_32(&[0x21, 0x43, 0x65], 0), 0x7E4A8634);
18 assert_eq!(murmur3_32(&[0x21, 0x43], 0), 0xA0F7B07A);
19 assert_eq!(murmur3_32(&[0x21], 0), 0x72661CF4);
20 }
21}
22
23pub const fn murmur3_32(data: &[u8], seed: u32) -> u32 {
25 let slice_size: usize = data.len();
26
27 let c1: u32 = 0xcc9e2d51;
28 let c2: u32 = 0x1b873593;
29 let r2 = 13;
30 let m = 5;
31 let n: u32 = 0xe6546b64;
32
33 let mut hash = seed;
34
35 let mut i = 0;
36 let iterator = slice_size / 4;
37 while i < iterator {
38 let data = [
39 data[i * 4],
40 data[i * 4 + 1],
41 data[i * 4 + 2],
42 data[i * 4 + 3],
43 ];
44 let mut k = u32::from_le_bytes(data);
45 k = k.wrapping_mul(c1);
46 k = k.rotate_left(15);
47 k = k.wrapping_mul(c2);
48
49 hash = hash ^ k;
50 hash = hash.rotate_left(r2);
51 hash = hash.wrapping_mul(m).wrapping_add(n);
52
53 i += 1;
54 }
55 match slice_size % 4 {
56 0 => (),
57 1 => {
58 let data = [data[i * 4], 0, 0, 0];
59 let k = mix_bytes_32(data);
60 hash = hash ^ k;
61 }
62 2 => {
63 let data = [data[i * 4], data[i * 4 + 1], 0, 0];
64 let k = mix_bytes_32(data);
65 hash = hash ^ k;
66 }
67 3 => {
68 let data = [data[i * 4], data[i * 4 + 1], data[i * 4 + 2], 0];
69 let k = mix_bytes_32(data);
70 hash = hash ^ k;
71 }
72 _ => unsafe { core::hint::unreachable_unchecked() },
73 }
74
75 hash = hash ^ slice_size as u32;
76 hash = hash ^ (hash.wrapping_shr(16));
77 hash = hash.wrapping_mul(0x85ebca6b);
78 hash = hash ^ (hash.wrapping_shr(13));
79 hash = hash.wrapping_mul(0xc2b2ae35);
80 hash = hash ^ (hash.wrapping_shr(16));
81
82 hash
83}
84
85const fn mix_bytes_32(data: [u8; 4]) -> u32 {
86 let r1 = 15;
87 let c1: u32 = 0xcc9e2d51;
88 let c2: u32 = 0x1b873593;
89 let mut k = u32::from_le_bytes(data);
90 k = k.wrapping_mul(c1);
91 k = k.rotate_left(r1);
92 k = k.wrapping_mul(c2);
93 return k;
94}