/** * ========================================================================= * File : fnv_hash.h * Project : 0 A.D. * Description : Fowler/Noll/Vo string hash * ========================================================================= */ // license: GPL; see lib/license.txt #include "precompiled.h" // FNV1-A hash - good for strings. // if len = 0 (default), treat buf as a C-string; // otherwise, hash bytes of buf. u32 fnv_hash(const void* buf, size_t len) { u32 h = 0x811c9dc5u; // give distinct values for different length 0 buffers. // value taken from FNV; it has no special significance. const u8* p = (const u8*)buf; // expected case: string if(!len) { while(*p) { h ^= *p++; h *= 0x01000193u; } } else { size_t bytes_left = len; while(bytes_left != 0) { h ^= *p++; h *= 0x01000193u; bytes_left--; } } return h; } // FNV1-A hash - good for strings. // if len = 0 (default), treat buf as a C-string; // otherwise, hash bytes of buf. u64 fnv_hash64(const void* buf, size_t len) { u64 h = 0xCBF29CE484222325ull; // give distinct values for different length 0 buffers. // value taken from FNV; it has no special significance. const u8* p = (const u8*)buf; // expected case: string if(!len) { while(*p) { h ^= *p++; h *= 0x100000001B3ull; } } else { size_t bytes_left = len; while(bytes_left != 0) { h ^= *p++; h *= 0x100000001B3ull; bytes_left--; } } return h; } // special version for strings: first converts to lowercase // (useful for comparing mixed-case filenames). // note: still need , e.g. to support non-0-terminated strings u32 fnv_lc_hash(const char* str, size_t len) { u32 h = 0x811c9dc5u; // give distinct values for different length 0 buffers. // value taken from FNV; it has no special significance. // expected case: string if(!len) { while(*str) { h ^= tolower(*str++); h *= 0x01000193u; } } else { size_t bytes_left = len; while(bytes_left != 0) { h ^= tolower(*str++); h *= 0x01000193u; bytes_left--; } } return h; }