/* Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE */ /* ver: 2.x.x - build: 2026-04-28 */ /* The zlib License Copyright (c) 2026 SD-Innovation S.A.S. This software is provided ‘as-is’, without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ #pragma once #include #include #include #include namespace sdi_toolBox::common::utils::hash { //-------------------------------------------------------------- /** * @brief Compute the FNV-1a 32-bit hash for a span of bytes. * * Primary API: accepts a `std::span` so callers can pass any * contiguous buffer without copies. * * @param data Span of bytes to hash. * @return std::uint32_t 32-bit FNV-1a hash. */ constexpr std::uint32_t fnv1a(std::span data) noexcept; /** * @brief Compute the FNV-1a 32-bit hash for a std::string_view. * * Convenience overload forwarding to the byte-based implementation. * * @param sv Input string view. * @return std::uint32_t The 32-bit FNV-1a hash. */ constexpr std::uint32_t fnv1a(std::string_view sv) noexcept; /** * @brief Compute the FNV-1a 32-bit hash for a trivially copyable POD object. * * The object is hashed as its raw bytes (binary representation). * Use only for POD/trivially-copyable types where this behaviour is intended. * * @tparam T Trivially copyable type. * @param value Reference to the object to hash. * @return std::uint32_t 32-bit FNV-1a hash. */ template requires std::is_trivially_copyable_v constexpr std::uint32_t fnv1a(const T &value) noexcept; /** * @brief Compute the FNV-1a 64-bit hash for a span of bytes. * * Primary API: accepts a `std::span` so callers can pass any * contiguous buffer without copies. * * @param data Span of bytes to hash. * @return std::uint64_t 64-bit FNV-1a hash. */ constexpr std::uint64_t fnv1a_64(std::span data) noexcept; /** * @brief Compute the FNV-1a 64-bit hash for a std::string_view. * * Convenience overload forwarding to the byte-based implementation. * * @param sv Input string view. * @return std::uint64_t The 64-bit FNV-1a hash. */ constexpr std::uint64_t fnv1a_64(std::string_view sv) noexcept; /** * @brief Compute the FNV-1a 64-bit hash for a trivially copyable POD object. * * The object is hashed as its raw bytes (binary representation). * Use only for POD/trivially-copyable types where this behaviour is intended. * * @tparam T Trivially copyable type. * @param value Reference to the object to hash. * @return std::uint64_t 64-bit FNV-1a hash. */ template requires std::is_trivially_copyable_v constexpr std::uint64_t fnv1a_64(const T &value) noexcept; //-------------------------------------------------------------- //-------------------------------------------------------------- /* Compute the FNV-1a 32-bit hash for a span of bytes */ inline constexpr std::uint32_t fnv1a(const std::span data) noexcept { constexpr std::uint32_t FNV_OFFSET_BASIS = 2166136261u; constexpr std::uint32_t FNV_PRIME = 16777619u; std::uint32_t hash = FNV_OFFSET_BASIS; for (const auto b : data) { hash ^= static_cast(std::to_integer(b)); hash *= FNV_PRIME; } return hash; } //-------------------------------------------------------------- /* Compute the FNV-1a 32-bit hash for a std::string_view */ inline constexpr std::uint32_t fnv1a(const std::string_view sv) noexcept { // Avoid reinterpret_cast on pointers: iterate characters (constexpr-friendly) constexpr std::uint32_t FNV_OFFSET_BASIS = 2166136261u; constexpr std::uint32_t FNV_PRIME = 16777619u; std::uint32_t hash = FNV_OFFSET_BASIS; for (char c : sv) { hash ^= static_cast(static_cast(c)); hash *= FNV_PRIME; } return hash; } //-------------------------------------------------------------- /* Compute the FNV-1a 32-bit hash for a trivially copyable POD object */ template requires std::is_trivially_copyable_v inline constexpr std::uint32_t fnv1a(const T &value) noexcept { // Use std::bit_cast to get bytes in a constexpr-friendly way auto bytes = std::bit_cast>(value); return fnv1a(std::span(bytes.data(), bytes.size())); } //-------------------------------------------------------------- /* Compute the FNV-1a 64-bit hash for a span of bytes */ inline constexpr std::uint64_t fnv1a_64(const std::span data) noexcept { constexpr std::uint64_t FNV_OFFSET_BASIS = 14695981039346656037ull; constexpr std::uint64_t FNV_PRIME = 1099511628211ull; std::uint64_t hash = FNV_OFFSET_BASIS; for (const auto b : data) { hash ^= static_cast(std::to_integer(b)); hash *= FNV_PRIME; } return hash; } //-------------------------------------------------------------- /* Compute the FNV-1a 64-bit hash for a std::string_view */ inline constexpr std::uint64_t fnv1a_64(const std::string_view sv) noexcept { // Iterate characters to remain constexpr-friendly constexpr std::uint64_t FNV_OFFSET_BASIS = 14695981039346656037ull; constexpr std::uint64_t FNV_PRIME = 1099511628211ull; std::uint64_t hash = FNV_OFFSET_BASIS; for (char c : sv) { hash ^= static_cast(static_cast(c)); hash *= FNV_PRIME; } return hash; } //-------------------------------------------------------------- /* Compute the FNV-1a 64-bit hash for a trivially copyable POD object */ template requires std::is_trivially_copyable_v inline constexpr std::uint64_t fnv1a_64(const T &value) noexcept { // Use std::bit_cast to get bytes in a constexpr-friendly way auto bytes = std::bit_cast>(value); return fnv1a_64(std::span(bytes.data(), bytes.size())); } //-------------------------------------------------------------- } // namespace sdi_toolBox::common::utils::hash