Created
June 2, 2021 09:47
-
-
Save epicabsol/4f041928eec0cae8b9ff0ebc326a1d79 to your computer and use it in GitHub Desktop.
64-bit FNV1a Hash (Run-Time and Compile-Time)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @file Hash.h | |
* @author Ben Garcia ([email protected]) | |
* @brief Provides run-time and compile-time 64-bit FNV1a hashing for strings and data. | |
* @version 1.0 | |
* @date 2021-06-02 | |
*/ | |
#pragma once | |
#include <cstdint> | |
#include <string> | |
typedef uint64_t hash64_t; | |
// FNV1a initialization parameters | |
constexpr hash64_t HashInitialValue = 0xCBF29CE484222325; | |
constexpr hash64_t HashPrime = 0x100000001B3; | |
/** | |
* @brief Computes the 64-bit FNV1a hash of the bytes at the given pointer. | |
* | |
* @param data A pointer to the data to compute the hash for. | |
* @param len The number of bytes from `data` to hash. | |
* @return The 64-bit FNV1a hash of the bytes. | |
*/ | |
inline hash64_t HashData(const void* data, const uint32_t len) { | |
const char* bytes = (char*)data; | |
hash64_t hash = HashInitialValue; | |
for (uint32_t i = 0; i < len; ++i) { | |
uint8_t value = bytes[i]; | |
hash = hash ^ value; | |
hash *= HashPrime; | |
} | |
return hash; | |
} | |
/** | |
* @brief Computes the 64-bit FNV1a hash of the bytes of the given string. | |
* | |
* @param text The string to compute the hash for. | |
* @return The 64-bit FNV1a hash of the string. | |
*/ | |
inline hash64_t HashString(const std::string& text) { | |
return HashData(text.c_str(), (uint32_t)text.length()); | |
} | |
/** | |
* @brief Computes the 64-bit FNV1a hash of the given null-terminated string literal at compile time. | |
* | |
* @param str The null-terminated string literal to compute the hash for. | |
* @param value For internal use. | |
* @param iter For internal use. | |
* @return The 64-bit FNV1a hash of the string. | |
* | |
* @note Source: https://notes.underscorediscovery.com/constexpr-fnv1a/ | |
*/ | |
inline constexpr hash64_t HashDataConst(const char* const str, const hash64_t value = HashInitialValue, const int iter = 0) noexcept { | |
return (str[0] == '\0') ? value : HashDataConst(&str[1], (value ^ hash64_t(str[0])) * HashPrime, iter + 1); | |
} | |
/** | |
* @brief Computes the 64-bit FNV1a hash of the given null-terminated string literal at compile time, leaving no trace of the original string. | |
* | |
* @param str The null-terminated string literal to compute the hash for. | |
*/ | |
#define STRINGHASH(str) std::integral_constant<hash64_t, HashDataConst(str, HashInitialValue, 0)>::value |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment