/* * hashFunctions.h * * Created on: Oct 3, 2010 * Author: sears */ #ifndef HASHFUNCTIONS_H_ #define HASHFUNCTIONS_H_ /** * This file contains a number of hash function implementations. * * Some are expensive, but general-purpose, and choose values with good * mathematical properties (i.e. CRC32). Others are faster, but special * purpose (assume their input is an integer), or provide weaker guarantees * about their outputs. * * FNV-1 hash implementations all have the following form: * * hash = offset_basis * for each octet_of_data to be hashed * hash = hash * FNV_prime * hash = hash xor octet_of_data * return hash * * * (From http://isthe.com/chongo/tech/comp/fnv/) */ #include #define stasis_hash_util_define_fnv_1(TYPE, FNV_prime, offset_basis) \ static inline TYPE stasis_util_hash_fnv_1_##TYPE(const byte* octets, int len){\ TYPE hash = offset_basis; \ \ for(int i = 0; i < len; i++) { \ hash = hash * FNV_prime; \ hash ^= octets[i]; \ } \ return hash; \ } \ /** * Implementation of FNV-1 (32-bit). Function is called stasis_util_hash_fnv_uint32_t(). */ stasis_hash_util_define_fnv_1(uint32_t, 16777619U, 2166136261U) /** * Implementation of FNV-1 (64-bit). Function is called stasis_util_hash_fnv_uint64_t(). */ stasis_hash_util_define_fnv_1(uint64_t, 1099511628211ULL, 14695981039346656037ULL) /** * Macro to define xor folding for dynamically set of bits. This is static inline, * so you can call the function and pass a constant value in as the second argument. * With gcc and -O2, it should propagate the constant, and this is as good as a * separte macro for each possible value of bits. * * Do not call this function if bits is less than 16. */ #define stasis_util_hash_define_fnv_xor_fold_big(TYPE) \ static inline TYPE stasis_util_hash_fnv_xor_fold_big_##TYPE(TYPE val, uint8_t bits) {\ const TYPE mask = ((TYPE)1<>bits) ^ (val & mask); \ } stasis_util_hash_define_fnv_xor_fold_big(uint32_t) stasis_util_hash_define_fnv_xor_fold_big(uint64_t) /** * @see stasis_util_hash_define_fnv_xor_fold_big * * Do not call this function if bits is greater than 16. */ #define stasis_util_hash_define_fnv_xor_fold_tiny(TYPE) \ static inline TYPE stasis_util_hash_fnv_xor_fold_tiny_##TYPE(TYPE val, uint8_t bits) {\ const TYPE mask = ((TYPE)1<>bits ^ val) & mask; \ } stasis_util_hash_define_fnv_xor_fold_tiny(uint32_t) static inline uint64_t stasis_util_hash_fnv_xor_fold_uint64_t(uint64_t val, uint8_t bits) { if(bits < 16) { return stasis_util_hash_fnv_xor_fold_tiny_uint32_t( stasis_util_hash_fnv_xor_fold_big_uint64_t(val, 32), bits ); } else if(bits < 32) { return stasis_util_hash_fnv_xor_fold_big_uint32_t( stasis_util_hash_fnv_xor_fold_big_uint64_t(val, 32), bits ); } else { return stasis_util_hash_fnv_xor_fold_big_uint64_t(val, bits); } } static inline uint32_t stasis_util_hash_fnv_xor_fold_uint32_t(uint32_t val, uint8_t bits) { if(bits < 16) { return stasis_util_hash_fnv_xor_fold_tiny_uint32_t(val, bits); } else { return stasis_util_hash_fnv_xor_fold_big_uint32_t(val, bits); } } #endif /* HASHFUNCTIONS_H_ */