]>
Commit | Line | Data |
---|---|---|
7ab026f4 MC |
1 | #include "hash.h" |
2 | ||
3 | inline uint32_t ROTL32 ( uint32_t x, int8_t r ) | |
4 | { | |
5 | return (x << r) | (x >> (32 - r)); | |
6 | } | |
7 | ||
8 | unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash) | |
9 | { | |
10 | // The following is MurmurHash3 (x86_32), see http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp | |
11 | uint32_t h1 = nHashSeed; | |
12 | const uint32_t c1 = 0xcc9e2d51; | |
13 | const uint32_t c2 = 0x1b873593; | |
14 | ||
15 | const int nblocks = vDataToHash.size() / 4; | |
16 | ||
17 | //---------- | |
18 | // body | |
19 | const uint32_t * blocks = (const uint32_t *)(&vDataToHash[0] + nblocks*4); | |
20 | ||
21 | for(int i = -nblocks; i; i++) | |
22 | { | |
23 | uint32_t k1 = blocks[i]; | |
24 | ||
25 | k1 *= c1; | |
26 | k1 = ROTL32(k1,15); | |
27 | k1 *= c2; | |
28 | ||
29 | h1 ^= k1; | |
30 | h1 = ROTL32(h1,13); | |
31 | h1 = h1*5+0xe6546b64; | |
32 | } | |
33 | ||
34 | //---------- | |
35 | // tail | |
36 | const uint8_t * tail = (const uint8_t*)(&vDataToHash[0] + nblocks*4); | |
37 | ||
38 | uint32_t k1 = 0; | |
39 | ||
40 | switch(vDataToHash.size() & 3) | |
41 | { | |
42 | case 3: k1 ^= tail[2] << 16; | |
43 | case 2: k1 ^= tail[1] << 8; | |
44 | case 1: k1 ^= tail[0]; | |
45 | k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; | |
46 | }; | |
47 | ||
48 | //---------- | |
49 | // finalization | |
50 | h1 ^= vDataToHash.size(); | |
51 | h1 ^= h1 >> 16; | |
52 | h1 *= 0x85ebca6b; | |
53 | h1 ^= h1 >> 13; | |
54 | h1 *= 0xc2b2ae35; | |
55 | h1 ^= h1 >> 16; | |
56 | ||
57 | return h1; | |
58 | } |