1 /* This is MurmurHash3. The original C++ code was placed in the public domain
2 * by its author, Austin Appleby.
3 *
4 * SPDX-License-Identifier: CC0-1.0
5 * Source: https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp */
6
7 #include "murmurhash3.h"
8 #include "string.h"
9
fmix(uint32_t h)10 static inline uint32_t fmix(uint32_t h)
11 {
12 h ^= h >> 16;
13 h *= 0x85ebca6b;
14 h ^= h >> 13;
15 h *= 0xc2b2ae35;
16 h ^= h >> 16;
17
18 return h;
19 }
20
rotl32(uint32_t x,int8_t r)21 static inline uint32_t rotl32(uint32_t x, int8_t r)
22 {
23 return (x << r) | (x >> (32 - r));
24 }
25
hash(const char * data,size_t len_)26 uint32_t hash(const char* data, size_t len_)
27 {
28 const int len = (int) len_;
29 const int nblocks = len / 4;
30
31 uint32_t h1 = 0xc062fb4a;
32
33 uint32_t c1 = 0xcc9e2d51;
34 uint32_t c2 = 0x1b873593;
35
36 //----------
37 // body
38
39 for(int i = 0; i < nblocks; ++i)
40 {
41 uint32_t k1;
42 memcpy(&k1, data + i * sizeof(k1), sizeof(k1));
43
44 k1 *= c1;
45 k1 = rotl32(k1, 15);
46 k1 *= c2;
47
48 h1 ^= k1;
49 h1 = rotl32(h1, 13);
50 h1 = h1*5+0xe6546b64;
51 }
52
53 //----------
54 // tail
55
56 const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
57
58 uint32_t k1 = 0;
59
60 switch(len & 3)
61 {
62 case 3: k1 ^= tail[2] << 16;
63 case 2: k1 ^= tail[1] << 8;
64 case 1: k1 ^= tail[0];
65 k1 *= c1; k1 = rotl32(k1,15); k1 *= c2; h1 ^= k1;
66 }
67
68 //----------
69 // finalization
70
71 h1 ^= len;
72
73 h1 = fmix(h1);
74
75 return h1;
76 }
77