/* This is MurmurHash3. The original C++ code was placed in the public domain * by its author, Austin Appleby. * * SPDX-License-Identifier: CC0-1.0 * Source: https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp */ #include "murmurhash3.h" #include "string.h" static inline uint32_t fmix(uint32_t h) { h ^= h >> 16; h *= 0x85ebca6b; h ^= h >> 13; h *= 0xc2b2ae35; h ^= h >> 16; return h; } static inline uint32_t rotl32(uint32_t x, int8_t r) { return (x << r) | (x >> (32 - r)); } uint32_t hash(const char* data, size_t len_) { const int len = (int) len_; const int nblocks = len / 4; uint32_t h1 = 0xc062fb4a; uint32_t c1 = 0xcc9e2d51; uint32_t c2 = 0x1b873593; //---------- // body for(int i = 0; i < nblocks; ++i) { uint32_t k1; memcpy(&k1, data + i * sizeof(k1), sizeof(k1)); k1 *= c1; k1 = rotl32(k1, 15); k1 *= c2; h1 ^= k1; h1 = rotl32(h1, 13); h1 = h1*5+0xe6546b64; } //---------- // tail const uint8_t * tail = (const uint8_t*)(data + nblocks*4); uint32_t k1 = 0; switch(len & 3) { case 3: k1 ^= tail[2] << 16; case 2: k1 ^= tail[1] << 8; case 1: k1 ^= tail[0]; k1 *= c1; k1 = rotl32(k1,15); k1 *= c2; h1 ^= k1; } //---------- // finalization h1 ^= len; h1 = fmix(h1); return h1; }