;;;; FNVHash.scm ;;;; Kon Lovett, Jan '06 (module FNVHash (;export *FNVHash FNVHash FNVHash-primitive ) (import scheme chicken foreign) (use message-digest hashes-support hash-utils) #> #include "hashes.h" /* Fowler/Noll/Vo hash * * The basis of this hash algorithm was taken from an idea sent * as reviewer comments to the IEEE POSIX P1003.2 committee by: * * Phong Vo (http://www.research.att.com/info/kpv/) * Glenn Fowler (http://www.research.att.com/~gsf/) * * In a subsequent ballot round: * * Landon Curt Noll (http://www.isthe.com/chongo/) * * improved on their algorithm. Some people tried this hash * and found that it worked rather well. In an EMail message * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. * * FNV hashes are designed to be fast while maintaining a low * collision rate. The FNV speed allows one to quickly hash lots * of data while maintaining a reasonable collision rate. See: * * http://www.isthe.com/chongo/tech/comp/fnv/index.html * * for more details as well as other forms of the FNV hash. * * Please do not copyright this code. This code is in the public domain. * * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * By: * chongo /\oo/\ * http://www.isthe.com/chongo/ * * Share and Enjoy! :-) */ /* * 32 bit FNV-1 and FNV-1a non-zero initial basis * * The FNV-1 initial basis is the FNV-0 hash of the following 32 octets: * * chongo /\../\ * * NOTE: The \'s above are not back-slashing escape characters. * They are literal ASCII backslash 0x5c characters. * * NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition. */ /* Useful with the gcc compiler with -O3 on many AMD & Intel CPUs. Undefine if this is the case. */ #define NO_FNV_GCC_OPTIMIZATION static uint32_t FNVHash( uint8_t *data, uint32_t length, uint32_t key ) { # define FNV1_32_INIT ((uint32_t) 0x811c9dc5) # define FNV_32_PRIME ((uint32_t) 0x01000193) if (! key) key = FNV1_32_INIT; if (data) { uint8_t *be = data + length; /* beyond end of buffer */ /* FNV-1 hash each octet in the buffer */ while (data < be) { /* multiply by the 32 bit FNV magic prime mod 2^32 */ #ifdef NO_FNV_GCC_OPTIMIZATION key *= FNV_32_PRIME; #else key += (key << 1) + (key << 4) + (key << 7) + (key << 8) + (key << 24); #endif /* xor the bottom with the current octet */ key ^= ((uint32_t) *data++); } } /* return our new hash value */ return key; # undef FNV_32_PRIME # undef FNV1_32_INIT } #undef NO_FNV_GCC_OPTIMIZATION #undef bitsizeof <# (include "hashes-macros") (gen-hash-api FNVHash) (gen-update-proc FNVHash) (gen-md-api FNVHash) ) ;module FNVHash