hash.h 1.3 KB

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