msg_tool\utils/
murmur2.rs1use std::hash::Hasher;
2
3const M: u32 = 0x5bd1e995;
4const R: u32 = 24;
5
6pub struct StreamingMurmur2 {
7 h: u32,
8 buf: [u8; 4],
9 buf_len: usize,
10}
11
12impl StreamingMurmur2 {
13 pub fn new(seed: u32, total_len: u32) -> Self {
15 let h = seed ^ total_len;
16 Self {
17 h,
18 buf: [0; 4],
19 buf_len: 0,
20 }
21 }
22}
23
24#[inline]
25fn mix_block(mut h: u32, mut k: u32) -> u32 {
26 k = k.wrapping_mul(M);
27 k ^= k >> R;
28 k = k.wrapping_mul(M);
29 h = h.wrapping_mul(M);
30 h ^= k;
31 h
32}
33
34impl Hasher for StreamingMurmur2 {
35 fn write(&mut self, mut bytes: &[u8]) {
36 if self.buf_len > 0 {
38 let needed = 4 - self.buf_len;
39 if bytes.len() >= needed {
40 self.buf[self.buf_len..4].copy_from_slice(&bytes[..needed]);
41 bytes = &bytes[needed..];
42
43 let k = u32::from_le_bytes(self.buf);
45 self.h = mix_block(self.h, k);
46 self.buf_len = 0;
47 } else {
48 self.buf[self.buf_len..self.buf_len + bytes.len()].copy_from_slice(bytes);
50 self.buf_len += bytes.len();
51 return;
52 }
53 }
54
55 while bytes.len() >= 4 {
57 let k = u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]);
58 self.h = mix_block(self.h, k);
59 bytes = &bytes[4..];
60 }
61
62 if !bytes.is_empty() {
64 self.buf[..bytes.len()].copy_from_slice(bytes);
65 self.buf_len = bytes.len();
66 }
67 }
68
69 fn finish(&self) -> u64 {
70 let mut h = self.h;
71
72 if self.buf_len > 0 {
74 if self.buf_len >= 3 {
75 h ^= (self.buf[2] as u32) << 16;
76 }
77 if self.buf_len >= 2 {
78 h ^= (self.buf[1] as u32) << 8;
79 }
80 if self.buf_len >= 1 {
81 h ^= self.buf[0] as u32;
82 }
83 h = h.wrapping_mul(M);
84 }
85
86 h ^= h >> 13;
88 h = h.wrapping_mul(M);
89 h ^= h >> 15;
90
91 h as u64
92 }
93}
94
95pub struct Murmur2 {
96 seed: u32,
97 buf: Vec<u8>,
98}
99
100impl Murmur2 {
101 pub fn new(seed: u32) -> Self {
102 Self {
103 seed,
104 buf: Vec::new(),
105 }
106 }
107}
108
109impl Hasher for Murmur2 {
110 fn write(&mut self, bytes: &[u8]) {
111 self.buf.extend_from_slice(bytes);
112 }
113
114 fn finish(&self) -> u64 {
115 let mut hasher = StreamingMurmur2::new(self.seed, self.buf.len() as u32);
116 hasher.write(&self.buf);
117 hasher.finish()
118 }
119}
120
121#[test]
122fn test_streaming_murmur2() {
123 let mut hasher = StreamingMurmur2::new(0, 4);
124 hasher.write(b"TEST");
125 assert_eq!(hasher.finish(), 2297143075);
126 hasher = StreamingMurmur2::new(0x300, 11);
127 hasher.write(b"HELLO");
128 hasher.write(b" WORLD");
129 assert_eq!(hasher.finish(), 3206656488);
130}