-
-
Save Lee-R/3839813 to your computer and use it in GitHub Desktop.
#include <cstdint> | |
namespace detail | |
{ | |
// FNV-1a 32bit hashing algorithm. | |
constexpr std::uint32_t fnv1a_32(char const* s, std::size_t count) | |
{ | |
return ((count ? fnv1a_32(s, count - 1) : 2166136261u) ^ s[count]) * 16777619u; | |
} | |
} // namespace detail | |
constexpr std::uint32_t operator"" _hash(char const* s, std::size_t count) | |
{ | |
return detail::fnv1a_32(s, count); | |
} | |
constexpr std::uint32_t check = "0123456789ABCDEF"_hash; | |
int main() | |
{ | |
// Compare against precomputed value. | |
static_assert(check == 141695047u, "bad hash value"); | |
return 0; | |
} |
Consider it public domain. Note however that I wrote this code 9 years ago. The 'constexpr' feature has advanced quite a bit since then (e.g. less need for recursion), so would I assume that there's newer fancier ways to do the same thing these days.
for the record, the original impl is somewhat different from the general definition of "hashing a string", as it hashes the trailing zero with the string, and rely on the fact that the underlying string is zero-terminated and 1 more byte longer than count
.
It's not wrong though, both are true for UDLs, but one may expect "GET"_hash == 2531704439
, while it actually provides 71161173
This is a c++11-complaint version without this problem.
inline constexpr std::uint32_t fnv1a_32(char const *s, std::size_t count) {
return count ? (fnv1a_32(s, count - 1) ^ s[count - 1]) * 16777619u : 2166136261u;
}
A comprehensive list of general purpose hash functions and their implementations can found here:
Hi, it is useful. What is license of this gist? MIT, public-domain, LGPL...?