-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathHashString.h
More file actions
113 lines (88 loc) · 4.28 KB
/
Copy pathHashString.h
File metadata and controls
113 lines (88 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// ========================================================================
// File: HashString.h
//
// Author: winterknife
//
// Description: This header file contains inline routines to hash short
// strings using non-cryptographic hash functions
//
// Modifications:
// 2025-08-24 Created
// 2025-09-22 Updated
// ========================================================================
// ========================================================================
// Header guards
// ========================================================================
#pragma once
// ========================================================================
// Includes
// ========================================================================
#include <stdint.h>
#include <sal.h>
// ========================================================================
// Macros
// ========================================================================
#pragma region MACROS
// 64-bit magic prime for Fowler/Noll/Vo (FNV) hash
// May not be modified
#define FNV_PRIME_64 0x100000001B3ULL
// 64-bit non-zero initial basis for FNV-1 hash
// May be modified as long as it is non-zero
#define FNV_OFFSET_BASIS_64 0xCBF29CE484222325ULL
// Macro to hash a short string at compile time
#define HASH_STRING_COMPILE_TIME(String) hash_string_fnv1a_64_as_constant(String, 0x95DD92DBA3D9E736ULL)
// Macro to hash a short string at run time
#define HASH_STRING_RUN_TIME(String, Length) hash_string_fnv1a_64(String, Length, 0x95DD92DBA3D9E736ULL)
#pragma endregion
// ========================================================================
// Inline routines
// ========================================================================
#pragma region INLINES
// Original implementation: http://www.isthe.com/chongo/tech/comp/fnv/index.html
// Authors: Phong Vo, Glenn Fowler, Landon Curt Noll
// Online hash lookup:
// curl -s -D "/dev/stderr" https://hashdb.openanalysis.net/hash/fnv1a_64/<hash value in decimal> | jq
/// @brief Hash a short string using 64-bit Fowler/Noll/Vo (FNV-1a) hash function
/// @tparam Type Type template parameter that acts as a placeholder for the type of character literals that make up the string
/// @param pctyString Pointer to a constant null-terminated string of ANSI/UNICODE characters
/// @param dwptrSize Number of characters in the string, excluding the terminal null
/// @param qwHash FNV offset basis (initial hash value)
/// @return 64-bit unsigned integer representing the hash value
template <typename Type>
__attribute__((always_inline)) inline constexpr unsigned long long hash_string_fnv1a_64(
_In_z_ const Type* pctyString,
_In_ size_t dwptrSize,
_In_ unsigned long long qwHash = FNV_OFFSET_BASIS_64
) noexcept {
// Init local variables
unsigned char byCurrent = 0;
// Hash each byte of the buffer
while (dwptrSize--) {
// Get current byte
byCurrent = static_cast<unsigned char>(*pctyString++);
// XOR the lower 8-bits of the hash value with the current byte
qwHash ^= byCurrent;
// Multiply the hash value by the 64-bit FNV magic prime mod 2^64
qwHash *= FNV_PRIME_64;
}
return qwHash;
}
#pragma endregion
// ========================================================================
// Immediate routines
// ========================================================================
#pragma region IMMEDIATES
/// @brief Hash a compile-time string constant at compile time using 64-bit Fowler/Noll/Vo (FNV-1a) hash function
/// @tparam Type Type template parameter that acts as a placeholder for the type of character literals that make up the string
/// @tparam Size Number of characters in the string, including the terminal null
/// @param tyarrInputData Reference to an array of constant ANSI/UNICODE characters
/// @param qwHash FNV offset basis (initial hash value)
/// @return 64-bit unsigned integer representing the hash value
template <typename Type, size_t Size>
consteval auto hash_string_fnv1a_64_as_constant(
_In_z_ const Type (&tyarrInputData)[Size],
_In_ unsigned long long qwHash = FNV_OFFSET_BASIS_64
) {
return hash_string_fnv1a_64(tyarrInputData, (Size - 1), qwHash);
}
#pragma endregion