Commit f59fd49f authored by Ondřej Surý's avatar Ondřej Surý

Add isc_hash32() and rename isc_hash_function() to isc_hash64()

As the names suggest the original isc_hash64 function returns 64-bit
long hash values and the isc_hash32() returns 32-bit values.
parent 344d66aa
......@@ -9,10 +9,6 @@
* information regarding copyright ownership.
*/
/*
* 32 bit Fowler/Noll/Vo FNV-1a hash code with modification for BIND
*/
#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>
......@@ -32,21 +28,25 @@
#include "isc/util.h"
static uint8_t isc_hash_key[16];
static uint8_t isc_hash32_key[8];
static bool hash_initialized = false;
static isc_once_t isc_hash_once = ISC_ONCE_INIT;
static void
isc_hash_initialize(void) {
uint64_t key[2] = { 0, 1 };
#if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
/*
* Set a constant key to help in problem reproduction should
* fuzzing find a crash or a hang.
*/
#else /* if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
uint64_t key[2] = { 0, 1 };
#if !FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
isc_entropy_get(key, sizeof(key));
#endif /* if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
memmove(isc_hash_key, key, sizeof(isc_hash_key));
#if !FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
isc_entropy_get(key, sizeof(key));
#endif /* if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
memmove(isc_hash32_key, key, sizeof(isc_hash32_key));
hash_initialized = true;
}
......@@ -104,8 +104,7 @@ isc_hash_set_initializer(const void *initializer) {
}
uint64_t
isc_hash_function(const void *data, const size_t length,
const bool case_sensitive) {
isc_hash64(const void *data, const size_t length, const bool case_sensitive) {
uint64_t hval;
REQUIRE(length == 0 || data != NULL);
......@@ -126,3 +125,27 @@ isc_hash_function(const void *data, const size_t length,
return (hval);
}
uint32_t
isc_hash32(const void *data, const size_t length, const bool case_sensitive) {
uint32_t hval;
REQUIRE(length == 0 || data != NULL);
RUNTIME_CHECK(isc_once_do(&isc_hash_once, isc_hash_initialize) ==
ISC_R_SUCCESS);
if (case_sensitive) {
isc_halfsiphash24(isc_hash_key, data, length, (uint8_t *)&hval);
} else {
uint8_t input[1024];
REQUIRE(length <= 1024);
for (unsigned int i = 0; i < length; i++) {
input[i] = maptolower[((const uint8_t *)data)[i]];
}
isc_halfsiphash24(isc_hash_key, input, length,
(uint8_t *)&hval);
}
return (hval);
}
......@@ -29,9 +29,12 @@ isc_hash_get_initializer(void);
void
isc_hash_set_initializer(const void *initializer);
#define isc_hash_function isc_hash64
uint32_t
isc_hash32(const void *data, const size_t length, const bool case_sensitive);
uint64_t
isc_hash_function(const void *data, const size_t length,
const bool case_sensitive);
isc_hash64(const void *data, const size_t length, const bool case_sensitive);
/*!<
* \brief Calculate a hash over data.
*
......@@ -41,7 +44,7 @@ isc_hash_function(const void *data, const size_t length,
* process using this library is run, but will have uniform
* distribution.
*
* isc_hash_function() calculates the hash from start to end over the
* isc_hash_32/64() calculates the hash from start to end over the
* input data.
*
* 'data' is the data to be hashed.
......@@ -52,9 +55,8 @@ isc_hash_function(const void *data, const size_t length,
* case_sensitive values. It should typically be false if the hash key
* is a DNS name.
*
* WARNING: In case of case insensitive input, the input buffer cannot
* be longer than 1024, which should be fine, as it is only used for
* DNS names.
* Returns:
* \li 32 or 64-bit hash value
*/
ISC_LANG_ENDDECLS
......
......@@ -238,7 +238,8 @@ isc_fsaccess_remove
isc_fsaccess_set
isc_glob
isc_globfree
isc_hash_function
isc_hash32
isc_hash64
isc_hash_get_initializer
isc_hash_set_initializer
isc_heap_create
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment