| 
									
										
										
										
											2013-11-20 11:46:18 +01:00
										 |  |  | #ifndef Py_HASH_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define Py_HASH_H
 | 
					
						
							|  |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  | extern "C" { | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Helpers for hash functions */ | 
					
						
							|  |  |  | #ifndef Py_LIMITED_API
 | 
					
						
							|  |  |  | PyAPI_FUNC(Py_hash_t) _Py_HashDouble(double); | 
					
						
							|  |  |  | PyAPI_FUNC(Py_hash_t) _Py_HashPointer(void*); | 
					
						
							|  |  |  | PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Prime multiplier used in string and various other hashes. */ | 
					
						
							|  |  |  | #define _PyHASH_MULTIPLIER 1000003UL  /* 0xf4243 */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Parameters used for the numeric hash implementation.  See notes for
 | 
					
						
							| 
									
										
										
										
											2017-11-09 11:55:34 -05:00
										 |  |  |    _Py_HashDouble in Python/pyhash.c.  Numeric hashes are based on | 
					
						
							| 
									
										
										
										
											2013-11-20 11:46:18 +01:00
										 |  |  |    reduction modulo the prime 2**_PyHASH_BITS - 1. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if SIZEOF_VOID_P >= 8
 | 
					
						
							|  |  |  | #  define _PyHASH_BITS 61
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #  define _PyHASH_BITS 31
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define _PyHASH_MODULUS (((size_t)1 << _PyHASH_BITS) - 1)
 | 
					
						
							|  |  |  | #define _PyHASH_INF 314159
 | 
					
						
							|  |  |  | #define _PyHASH_NAN 0
 | 
					
						
							|  |  |  | #define _PyHASH_IMAG _PyHASH_MULTIPLIER
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* hash secret
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * memory layout on 64 bit systems | 
					
						
							|  |  |  |  *   cccccccc cccccccc cccccccc  uc -- unsigned char[24] | 
					
						
							|  |  |  |  *   pppppppp ssssssss ........  fnv -- two Py_hash_t | 
					
						
							| 
									
										
										
										
											2016-09-06 13:24:00 -07:00
										 |  |  |  *   k0k0k0k0 k1k1k1k1 ........  siphash -- two uint64_t | 
					
						
							| 
									
										
										
										
											2013-11-20 11:46:18 +01:00
										 |  |  |  *   ........ ........ ssssssss  djbx33a -- 16 bytes padding + one Py_hash_t | 
					
						
							|  |  |  |  *   ........ ........ eeeeeeee  pyexpat XML hash salt | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * memory layout on 32 bit systems | 
					
						
							|  |  |  |  *   cccccccc cccccccc cccccccc  uc | 
					
						
							|  |  |  |  *   ppppssss ........ ........  fnv -- two Py_hash_t | 
					
						
							| 
									
										
										
										
											2016-09-06 13:24:00 -07:00
										 |  |  |  *   k0k0k0k0 k1k1k1k1 ........  siphash -- two uint64_t (*) | 
					
						
							| 
									
										
										
										
											2013-11-20 11:46:18 +01:00
										 |  |  |  *   ........ ........ ssss....  djbx33a -- 16 bytes padding + one Py_hash_t | 
					
						
							|  |  |  |  *   ........ ........ eeee....  pyexpat XML hash salt | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * (*) The siphash member may not be available on 32 bit platforms without | 
					
						
							|  |  |  |  *     an unsigned int64 data type. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-01-03 21:36:49 +01:00
										 |  |  | #ifndef Py_LIMITED_API
 | 
					
						
							| 
									
										
										
										
											2013-11-20 11:46:18 +01:00
										 |  |  | typedef union { | 
					
						
							|  |  |  |     /* ensure 24 bytes */ | 
					
						
							|  |  |  |     unsigned char uc[24]; | 
					
						
							|  |  |  |     /* two Py_hash_t for FNV */ | 
					
						
							|  |  |  |     struct { | 
					
						
							|  |  |  |         Py_hash_t prefix; | 
					
						
							|  |  |  |         Py_hash_t suffix; | 
					
						
							|  |  |  |     } fnv; | 
					
						
							|  |  |  |     /* two uint64 for SipHash24 */ | 
					
						
							|  |  |  |     struct { | 
					
						
							| 
									
										
										
										
											2016-09-06 13:24:00 -07:00
										 |  |  |         uint64_t k0; | 
					
						
							|  |  |  |         uint64_t k1; | 
					
						
							| 
									
										
										
										
											2013-11-20 11:46:18 +01:00
										 |  |  |     } siphash; | 
					
						
							|  |  |  |     /* a different (!) Py_hash_t for small string optimization */ | 
					
						
							|  |  |  |     struct { | 
					
						
							|  |  |  |         unsigned char padding[16]; | 
					
						
							|  |  |  |         Py_hash_t suffix; | 
					
						
							|  |  |  |     } djbx33a; | 
					
						
							|  |  |  |     struct { | 
					
						
							|  |  |  |         unsigned char padding[16]; | 
					
						
							|  |  |  |         Py_hash_t hashsalt; | 
					
						
							|  |  |  |     } expat; | 
					
						
							|  |  |  | } _Py_HashSecret_t; | 
					
						
							|  |  |  | PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret; | 
					
						
							| 
									
										
										
										
											2014-01-03 21:36:49 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-11-20 11:46:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef Py_DEBUG
 | 
					
						
							|  |  |  | PyAPI_DATA(int) _Py_HashSecret_Initialized; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* hash function definition */ | 
					
						
							|  |  |  | #ifndef Py_LIMITED_API
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |     Py_hash_t (*const hash)(const void *, Py_ssize_t); | 
					
						
							|  |  |  |     const char *name; | 
					
						
							|  |  |  |     const int hash_bits; | 
					
						
							|  |  |  |     const int seed_bits; | 
					
						
							|  |  |  | } PyHash_FuncDef; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* cutoff for small string DJBX33A optimization in range [1, cutoff).
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * About 50% of the strings in a typical Python application are smaller than | 
					
						
							|  |  |  |  * 6 to 7 chars. However DJBX33A is vulnerable to hash collision attacks. | 
					
						
							|  |  |  |  * NEVER use DJBX33A for long strings! | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * A Py_HASH_CUTOFF of 0 disables small string optimization. 32 bit platforms | 
					
						
							|  |  |  |  * should use a smaller cutoff because it is easier to create colliding | 
					
						
							|  |  |  |  * strings. A cutoff of 7 on 64bit platforms and 5 on 32bit platforms should | 
					
						
							|  |  |  |  * provide a decent safety margin. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #ifndef Py_HASH_CUTOFF
 | 
					
						
							|  |  |  | #  define Py_HASH_CUTOFF 0
 | 
					
						
							|  |  |  | #elif (Py_HASH_CUTOFF > 7 || Py_HASH_CUTOFF < 0)
 | 
					
						
							|  |  |  | #  error Py_HASH_CUTOFF must in range 0...7.
 | 
					
						
							|  |  |  | #endif /* Py_HASH_CUTOFF */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* hash algorithm selection
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The values for Py_HASH_SIPHASH24 and Py_HASH_FNV are hard-coded in the | 
					
						
							|  |  |  |  * configure script. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * - FNV is available on all platforms and architectures. | 
					
						
							| 
									
										
										
										
											2016-09-06 13:24:00 -07:00
										 |  |  |  * - SIPHASH24 only works on plaforms that don't require aligned memory for integers. | 
					
						
							| 
									
										
										
										
											2013-11-20 11:46:18 +01:00
										 |  |  |  * - With EXTERNAL embedders can provide an alternative implementation with:: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     PyHash_FuncDef PyHash_Func = {...}; | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * XXX: Figure out __declspec() for extern PyHash_FuncDef. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define Py_HASH_EXTERNAL 0
 | 
					
						
							|  |  |  | #define Py_HASH_SIPHASH24 1
 | 
					
						
							|  |  |  | #define Py_HASH_FNV 2
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef Py_HASH_ALGORITHM
 | 
					
						
							| 
									
										
										
										
											2016-09-06 13:24:00 -07:00
										 |  |  | #  ifndef HAVE_ALIGNED_REQUIRED
 | 
					
						
							| 
									
										
										
										
											2013-11-20 11:46:18 +01:00
										 |  |  | #    define Py_HASH_ALGORITHM Py_HASH_SIPHASH24
 | 
					
						
							|  |  |  | #  else
 | 
					
						
							|  |  |  | #    define Py_HASH_ALGORITHM Py_HASH_FNV
 | 
					
						
							|  |  |  | #  endif /* uint64_t && uint32_t && aligned */
 | 
					
						
							|  |  |  | #endif /* Py_HASH_ALGORITHM */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* !Py_HASH_H */
 |