From: Alan T. DeKok Date: Sat, 24 Jan 2026 17:33:46 +0000 (-0500) Subject: add 64-bit variants of fr_hash() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=58fce92b63f31079206eb1fa8cef6a2867197c7d;p=thirdparty%2Ffreeradius-server.git add 64-bit variants of fr_hash() --- diff --git a/src/lib/util/hash.c b/src/lib/util/hash.c index ca513c0bb1e..d65b4421c73 100644 --- a/src/lib/util/hash.c +++ b/src/lib/util/hash.c @@ -895,6 +895,61 @@ uint32_t fr_hash_case_string(char const *p) return hash; } +/* + * 64-bit variants of the above functions/ + */ +#undef FNV_MAGIC_INIT +#undef FNV_MAGIC_PRIME +#define FNV_MAGIC_INIT ((uint64_t) 0xcbf29ce484222325) +#define FNV_MAGIC_PRIME ((uint64_t) 0x01000193) + +/* + * A 64-bit version of the above hash + */ +uint64_t fr_hash64(void const *data, size_t size) +{ + uint8_t const *p = data; + uint8_t const *q = p + size; + uint64_t hash = FNV_MAGIC_INIT; + + /* + * FNV-1 hash each octet in the buffer + */ + while (p != q) { + /* + * XOR the 8-bit quantity into the bottom of + * the hash. + */ + hash ^= (uint32_t) (*p++); + + /* + * Multiple by 32-bit magic FNV prime, mod 2^32 + */ + hash *= FNV_MAGIC_PRIME; + } + + return hash; +} + +/* + * Continue hashing data. + */ +uint64_t fr_hash64_update(void const *data, size_t size, uint64_t hash) +{ + uint8_t const *p = data; + uint8_t const *q; + + if (size == 0) return hash; /* Avoid ubsan issues with access NULL pointer */ + + q = p + size; + while (p < q) { + hash *= FNV_MAGIC_PRIME; + hash ^= (uint64_t) (*p++); + } + + return hash; +} + /** Check hash table is sane * */ diff --git a/src/lib/util/hash.h b/src/lib/util/hash.h index 67987b3f9f8..0bee1775e74 100644 --- a/src/lib/util/hash.h +++ b/src/lib/util/hash.h @@ -52,6 +52,9 @@ uint32_t fr_hash_update(void const *data, size_t size, uint32_t hash); uint32_t fr_hash_string(char const *p); uint32_t fr_hash_case_string(char const *p); +uint64_t fr_hash64(void const *, size_t); +uint64_t fr_hash64_update(void const *data, size_t size, uint64_t hash); + typedef struct fr_hash_table_s fr_hash_table_t; typedef int (*fr_hash_table_walk_t)(void *data, void *uctx);