]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add 64-bit variants of fr_hash()
authorAlan T. DeKok <aland@freeradius.org>
Sat, 24 Jan 2026 17:33:46 +0000 (12:33 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 24 Jan 2026 17:33:46 +0000 (12:33 -0500)
src/lib/util/hash.c
src/lib/util/hash.h

index ca513c0bb1ec979e75a30f5a3ebfd46c60b25dbe..d65b4421c73ed3a6276e50a7d592a608e0f9da72 100644 (file)
@@ -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
  *
  */
index 67987b3f9f81c95cb3c19e12a03609b71322415f..0bee1775e740320438d7e7607e5a1bb1dfabf057 100644 (file)
@@ -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);