pyhash.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #ifndef Py_HASH_H
  2. #define Py_HASH_H
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. /* Helpers for hash functions */
  7. #ifndef Py_LIMITED_API
  8. PyAPI_FUNC(Py_hash_t) _Py_HashDouble(PyObject *, double);
  9. PyAPI_FUNC(Py_hash_t) _Py_HashPointer(const void*);
  10. // Similar to _Py_HashPointer(), but don't replace -1 with -2
  11. PyAPI_FUNC(Py_hash_t) _Py_HashPointerRaw(const void*);
  12. PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t);
  13. #endif
  14. /* Prime multiplier used in string and various other hashes. */
  15. #define _PyHASH_MULTIPLIER 1000003UL /* 0xf4243 */
  16. /* Parameters used for the numeric hash implementation. See notes for
  17. _Py_HashDouble in Python/pyhash.c. Numeric hashes are based on
  18. reduction modulo the prime 2**_PyHASH_BITS - 1. */
  19. #if SIZEOF_VOID_P >= 8
  20. # define _PyHASH_BITS 61
  21. #else
  22. # define _PyHASH_BITS 31
  23. #endif
  24. #define _PyHASH_MODULUS (((size_t)1 << _PyHASH_BITS) - 1)
  25. #define _PyHASH_INF 314159
  26. #define _PyHASH_IMAG _PyHASH_MULTIPLIER
  27. /* hash secret
  28. *
  29. * memory layout on 64 bit systems
  30. * cccccccc cccccccc cccccccc uc -- unsigned char[24]
  31. * pppppppp ssssssss ........ fnv -- two Py_hash_t
  32. * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t
  33. * ........ ........ ssssssss djbx33a -- 16 bytes padding + one Py_hash_t
  34. * ........ ........ eeeeeeee pyexpat XML hash salt
  35. *
  36. * memory layout on 32 bit systems
  37. * cccccccc cccccccc cccccccc uc
  38. * ppppssss ........ ........ fnv -- two Py_hash_t
  39. * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t (*)
  40. * ........ ........ ssss.... djbx33a -- 16 bytes padding + one Py_hash_t
  41. * ........ ........ eeee.... pyexpat XML hash salt
  42. *
  43. * (*) The siphash member may not be available on 32 bit platforms without
  44. * an unsigned int64 data type.
  45. */
  46. #ifndef Py_LIMITED_API
  47. typedef union {
  48. /* ensure 24 bytes */
  49. unsigned char uc[24];
  50. /* two Py_hash_t for FNV */
  51. struct {
  52. Py_hash_t prefix;
  53. Py_hash_t suffix;
  54. } fnv;
  55. /* two uint64 for SipHash24 */
  56. struct {
  57. uint64_t k0;
  58. uint64_t k1;
  59. } siphash;
  60. /* a different (!) Py_hash_t for small string optimization */
  61. struct {
  62. unsigned char padding[16];
  63. Py_hash_t suffix;
  64. } djbx33a;
  65. struct {
  66. unsigned char padding[16];
  67. Py_hash_t hashsalt;
  68. } expat;
  69. } _Py_HashSecret_t;
  70. PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret;
  71. #ifdef Py_DEBUG
  72. PyAPI_DATA(int) _Py_HashSecret_Initialized;
  73. #endif
  74. /* hash function definition */
  75. typedef struct {
  76. Py_hash_t (*const hash)(const void *, Py_ssize_t);
  77. const char *name;
  78. const int hash_bits;
  79. const int seed_bits;
  80. } PyHash_FuncDef;
  81. PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void);
  82. #endif
  83. /* cutoff for small string DJBX33A optimization in range [1, cutoff).
  84. *
  85. * About 50% of the strings in a typical Python application are smaller than
  86. * 6 to 7 chars. However DJBX33A is vulnerable to hash collision attacks.
  87. * NEVER use DJBX33A for long strings!
  88. *
  89. * A Py_HASH_CUTOFF of 0 disables small string optimization. 32 bit platforms
  90. * should use a smaller cutoff because it is easier to create colliding
  91. * strings. A cutoff of 7 on 64bit platforms and 5 on 32bit platforms should
  92. * provide a decent safety margin.
  93. */
  94. #ifndef Py_HASH_CUTOFF
  95. # define Py_HASH_CUTOFF 0
  96. #elif (Py_HASH_CUTOFF > 7 || Py_HASH_CUTOFF < 0)
  97. # error Py_HASH_CUTOFF must in range 0...7.
  98. #endif /* Py_HASH_CUTOFF */
  99. /* hash algorithm selection
  100. *
  101. * The values for Py_HASH_* are hard-coded in the
  102. * configure script.
  103. *
  104. * - FNV and SIPHASH* are available on all platforms and architectures.
  105. * - With EXTERNAL embedders can provide an alternative implementation with::
  106. *
  107. * PyHash_FuncDef PyHash_Func = {...};
  108. *
  109. * XXX: Figure out __declspec() for extern PyHash_FuncDef.
  110. */
  111. #define Py_HASH_EXTERNAL 0
  112. #define Py_HASH_SIPHASH24 1
  113. #define Py_HASH_FNV 2
  114. #define Py_HASH_SIPHASH13 3
  115. #ifndef Py_HASH_ALGORITHM
  116. # ifndef HAVE_ALIGNED_REQUIRED
  117. # define Py_HASH_ALGORITHM Py_HASH_SIPHASH13
  118. # else
  119. # define Py_HASH_ALGORITHM Py_HASH_FNV
  120. # endif /* uint64_t && uint32_t && aligned */
  121. #endif /* Py_HASH_ALGORITHM */
  122. #ifdef __cplusplus
  123. }
  124. #endif
  125. #endif /* !Py_HASH_H */