File: /Users/paulross/dev/Python-3.6.2/Include/pyhash.h

Green shading in the line number column means the source is part of the translation unit, red means it is conditionally excluded. Highlighted line numbers link to the translation unit page. Highlighted macros link to the macro page.

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