python (3.12.0)

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