#ifndef HASH_H #define HASH_H #include #include __attribute__((access (read_only, 1), nonnull, pure)) uint64_t hash(const uint8_t* data, size_t size); __attribute__((pure)) uint64_t uint64_hash(uint64_t key); #if defined(HASH_IMP) || defined(IMPLEMENTATIONS) /* Thomas Wang 64 bit mix hash function. */ uint64_t uint64_hash(uint64_t key) { key = (~key) + (key << 21); // key *= (1 << 21) - 1; key -= 1; key = key ^ (key >> 24); key = key + (key << 3) + (key << 8); // key *= 1 + (1 << 3) + (1 << 8) key = key ^ (key >> 14); key = key + (key << 2) + (key << 4); // key *= 1 + (1 << 2) + (1 << 4) key = key ^ (key >> 28); key = key + (key << 31); // key *= 1 + (1 << 31) return key; } uint64_t hash(const uint8_t* data, size_t size) { static uint8_t _primes_list[] = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173 }; static uint8_t _primes_list_size = 10; uint64_t max = UINT64_MAX >> 1; uint64_t ret = 1; uint8_t p = 0; size_t i = 0; byte_t b = 0; for ( i = 0; i < size; ++i ) { b = data[i]; p = _primes_list[(i + b) % _primes_list_size]; ret = (ret * (b * p)) % max; } return ret; } #endif /* HASH_IMP || IMPLEMENTATIONS */ #endif