1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
/****************************************************************
* *
* Copyright (c) 2011-2023 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#ifndef MURMURHASH_H
#define MURMURHASH_H 1
/*-----------------------------------------------------------------------------
* MurmurHash3 was written by Austin Appleby, and is placed in the public
* domain. The author hereby disclaims copyright to this source code.
*
* This version converted to C for use in GT.M by FIS.
* The original implementation has been superseded by an incremental,
* endian stable one, with only a few core pieces remaining.
*-----------------------------------------------------------------------------*/
#define ROTL32(X,Y) (((X) << (Y)) | ((X) >> (32 - (Y))))
#define ROTL64(X,Y) (((X) << (Y)) | ((X) >> (64 - (Y))))
#define BIG_CONSTANT(x) (x##LLU)
typedef struct
{
gtm_uint8 one, two;
} gtm_uint16;
typedef struct
{
gtm_uint16 h, c;
int carry_bytes;
} hash128_state_t;
#define HASH128_STATE_INIT(STATE, SEED) \
MBSTART { \
(STATE).h.one = (STATE).h.two = (SEED); \
(STATE).c.one = (STATE).c.two = 0; \
(STATE).carry_bytes = 0; \
} MBEND
#define HASH128_EXTRACT_32(HASH) ((uint4)(HASH).one)
/* Classic non-incremental, endian unstable, implementation. */
void MurmurHash3_x86_32(const void *key, int len, uint4 seed, void *out);
/* Incremental, endian stable implementation. */
inline void gtmmrhash_32(const void *key, int len, uint4 seed, uint4 *out4);
inline void gtmmrhash_128(const void *key, int len, uint4 seed, gtm_uint16 *out);
int gtmmrhash_128_ingest(hash128_state_t *state, const void *key, int len);
void gtmmrhash_128_result(hash128_state_t *state, uint4 total_len, gtm_uint16 *out);
inline void gtmmrhash_128_hex(const gtm_uint16 *hash, unsigned char *out);
inline void gtmmrhash_128_bytes(const gtm_uint16 *hash, unsigned char *out);
/* Implementation */
inline void gtmmrhash_128(const void *key, int len, uint4 seed, gtm_uint16 *out)
{
hash128_state_t state;
HASH128_STATE_INIT(state, seed);
#ifndef STATIC_ANALYSIS
/* Don't do this assert if SCA since we are inline & gtm_abrt() won't resolve */
assert((state.carry_bytes == 0) && (state.c.one == 0) && (state.c.two == 0));
#endif
gtmmrhash_128_ingest(&state, key, len);
gtmmrhash_128_result(&state, len, out);
}
inline void gtmmrhash_32(const void *key, int len, uint4 seed, uint4 *out4)
{
gtm_uint16 out16;
gtmmrhash_128(key, len, seed, &out16);
*out4 = HASH128_EXTRACT_32(out16);
}
inline void gtmmrhash_128_bytes(const gtm_uint16 *hash, unsigned char *out)
{
# ifdef BIGENDIAN
# define EXTRACT_BYTE(X, N) (((uint64_t)(X) & ((uint64_t)0xff << (N) * 8)) >> (N) * 8)
out[0] = EXTRACT_BYTE(hash->one, 0);
out[1] = EXTRACT_BYTE(hash->one, 1);
out[2] = EXTRACT_BYTE(hash->one, 2);
out[3] = EXTRACT_BYTE(hash->one, 3);
out[4] = EXTRACT_BYTE(hash->one, 4);
out[5] = EXTRACT_BYTE(hash->one, 5);
out[6] = EXTRACT_BYTE(hash->one, 6);
out[7] = EXTRACT_BYTE(hash->one, 7);
out[8] = EXTRACT_BYTE(hash->two, 0);
out[9] = EXTRACT_BYTE(hash->two, 1);
out[10] = EXTRACT_BYTE(hash->two, 2);
out[11] = EXTRACT_BYTE(hash->two, 3);
out[12] = EXTRACT_BYTE(hash->two, 4);
out[13] = EXTRACT_BYTE(hash->two, 5);
out[14] = EXTRACT_BYTE(hash->two, 6);
out[15] = EXTRACT_BYTE(hash->two, 7);
# else
((gtm_uint8 *)out)[0] = hash->one;
((gtm_uint8 *)out)[1] = hash->two;
# endif
}
inline void gtmmrhash_128_hex(const gtm_uint16 *hash, unsigned char *out)
{
int i;
unsigned char bytes[16], n;
gtmmrhash_128_bytes(hash, bytes);
for (i = 0; i < 16; i++)
{
n = bytes[i] & 0xf;
out[i * 2 + 1] = (n < 10) ? (n + '0') : (n - 10 + 'a');
n = (bytes[i] >> 4) & 0xf;
out[i * 2] = (n < 10) ? (n + '0') : (n - 10 + 'a');
}
}
#endif
/*-----------------------------------------------------------------------------*/
|