There may come a time that you don’t want to leave strings in your executable but still need to do some kind of string comparison. For that I use the compile-time constexpr
features of modern c++ compilers.
1
2
3
4
| auto hash = CX_Fnv1a("shady_lib.dll")
// in case you need to ignore case, string will be converted to lowercase
auto hash = CX_IFnv1a("shady_lib.dll")
|
Check the output binary using string.exe
, there will be no trace of shady_lib.dll
other than a number.
fnv1a.hpp
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
| #pragma once
#define CX_Fnv1a(s) FNV1A::FnvHash<s>::v
#define CX_IFnv1a(s) FNV1A::IFnvHash<s>::v
namespace FNV1A
{
typedef unsigned long long fnvhash;
constexpr fnvhash FnvValue = 14695981039346656037ull;
constexpr fnvhash FnvPrime = 1099511628211ull;
// CASE-SENSITIVE
template<typename T>
constexpr fnvhash Hash(T c) noexcept
{
fnvhash v = FnvValue;
for (; *c; ++c) v = (v ^ static_cast<fnvhash>(*c)) * FnvPrime;
return v;
}
template<typename T>
constexpr fnvhash HashFixed(T c, size_t s) noexcept
{
fnvhash v = FnvValue;
for (size_t i = 0; i < s; ++i) v = (v ^ static_cast<fnvhash>(c[i])) * FnvPrime;
return v;
}
template <typename CharT, size_t N>
struct FnvString
{
fnvhash v;
constexpr FnvString(const CharT(&foo)[N + 1]) noexcept
: v(Hash(foo))
{}
};
template <typename CharT, size_t N>
FnvString(const CharT(&str)[N])->FnvString<CharT, N - 1>;
template <FnvString s>
struct FnvHash { enum : fnvhash { v = s.v }; };
// CASE-INSENSITIVE
template<typename CharT>
constexpr auto ToLower(CharT c) noexcept
{
return (c >= 65 && c <= 90) ? static_cast<CharT>(c + 32) : c;
}
template<typename T>
constexpr fnvhash IHash(T c) noexcept
{
fnvhash v = FnvValue;
for (; *c; ++c) v = (v ^ static_cast<fnvhash>(ToLower(*c))) * FnvPrime;
return v;
}
template<typename T>
constexpr fnvhash IHashFixed(T c, size_t s) noexcept
{
fnvhash v = FnvValue;
for (size_t i = 0; i < s; ++i) v = (v ^ static_cast<fnvhash>(ToLower(c[i]))) * FnvPrime;
return v;
}
template <typename CharT, size_t N>
struct IFnvString
{
fnvhash v;
constexpr IFnvString(const CharT(&foo)[N + 1]) noexcept
: v(IHash(foo))
{}
};
template <typename CharT, size_t N>
IFnvString(const CharT(&str)[N])->IFnvString<CharT, N - 1>;
template <IFnvString s>
struct IFnvHash { enum : fnvhash { v = s.v }; };
}
|