UNPKG

1.65 kBtext/x-cView Raw
1#include <stdint.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "murmur3.h"
6
7static inline uint32_t
8read32(const void *src) {
9#if defined(MRMR_LITTLE_ENDIAN)
10 uint32_t w;
11 memcpy(&w, src, sizeof w);
12 return w;
13#else
14 const uint8_t *p = (const uint8_t *)src;
15 return ((uint32_t)(p[0]) << 0)
16 | ((uint32_t)(p[1]) << 8)
17 | ((uint32_t)(p[2]) << 16)
18 | ((uint32_t)(p[3]) << 24);
19#endif
20}
21
22static inline uint32_t
23rotl32(uint32_t x, int8_t r) {
24 return (x << r) | (x >> (32 - r));
25}
26
27uint32_t
28mrmr_murmur3_sum(const uint8_t *data, size_t len, uint32_t seed) {
29 uint32_t h1 = seed;
30
31 if (len > 0) {
32 const uint32_t c1 = 0xcc9e2d51;
33 const uint32_t c2 = 0x1b873593;
34
35 const int32_t nblocks = len / 4;
36
37 const uint8_t *blocks = &data[0] + nblocks * 4;
38
39 for (int32_t i = -nblocks; i; i++) {
40 uint32_t k1 = read32(blocks + i * 4);
41
42 k1 *= c1;
43 k1 = rotl32(k1, 15);
44 k1 *= c2;
45
46 h1 ^= k1;
47 h1 = rotl32(h1, 13);
48 h1 = h1 * 5 + 0xe6546b64;
49 }
50
51 const uint8_t *tail = (const uint8_t *)(&data[0] + nblocks * 4);
52
53 uint32_t k1 = 0;
54
55 switch (len & 3) {
56 case 3:
57 k1 ^= tail[2] << 16;
58 case 2:
59 k1 ^= tail[1] << 8;
60 case 1:
61 k1 ^= tail[0];
62 k1 *= c1;
63 k1 = rotl32(k1, 15);
64 k1 *= c2;
65 h1 ^= k1;
66 }
67 }
68
69 h1 ^= len;
70 h1 ^= h1 >> 16;
71 h1 *= 0x85ebca6b;
72 h1 ^= h1 >> 13;
73 h1 *= 0xc2b2ae35;
74 h1 ^= h1 >> 16;
75
76 return h1;
77}
78
79uint32_t
80mrmr_murmur3_tweak(
81 const uint8_t *data,
82 size_t len,
83 uint32_t n,
84 uint32_t tweak
85) {
86 uint32_t seed = (n * 0xfba4c795ul) + tweak;
87 return mrmr_murmur3_sum(data, len, seed);
88}