]> git.proxmox.com Git - ceph.git/blob - ceph/src/civetweb/src/third_party/duktape-1.3.0/src-separate/duk_util_hashbytes.c
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / civetweb / src / third_party / duktape-1.3.0 / src-separate / duk_util_hashbytes.c
1 /*
2 * Hash function duk_util_hashbytes().
3 *
4 * Currently, 32-bit MurmurHash2.
5 *
6 * Don't rely on specific hash values; hash function may be endianness
7 * dependent, for instance.
8 */
9
10 #include "duk_internal.h"
11
12 /* 'magic' constants for Murmurhash2 */
13 #define DUK__MAGIC_M ((duk_uint32_t) 0x5bd1e995UL)
14 #define DUK__MAGIC_R 24
15
16 DUK_INTERNAL duk_uint32_t duk_util_hashbytes(const duk_uint8_t *data, duk_size_t len, duk_uint32_t seed) {
17 duk_uint32_t h = seed ^ ((duk_uint32_t) len);
18
19 while (len >= 4) {
20 /* Portability workaround is required for platforms without
21 * unaligned access. The replacement code emulates little
22 * endian access even on big endian architectures, which is
23 * OK as long as it is consistent for a build.
24 */
25 #ifdef DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS
26 duk_uint32_t k = *((duk_uint32_t *) (void *) data);
27 #else
28 duk_uint32_t k = ((duk_uint32_t) data[0]) |
29 (((duk_uint32_t) data[1]) << 8) |
30 (((duk_uint32_t) data[2]) << 16) |
31 (((duk_uint32_t) data[3]) << 24);
32 #endif
33
34 k *= DUK__MAGIC_M;
35 k ^= k >> DUK__MAGIC_R;
36 k *= DUK__MAGIC_M;
37 h *= DUK__MAGIC_M;
38 h ^= k;
39 data += 4;
40 len -= 4;
41 }
42
43 switch (len) {
44 case 3: h ^= data[2] << 16;
45 case 2: h ^= data[1] << 8;
46 case 1: h ^= data[0];
47 h *= DUK__MAGIC_M;
48 }
49
50 h ^= h >> 13;
51 h *= DUK__MAGIC_M;
52 h ^= h >> 15;
53
54 return h;
55 }