Created
December 18, 2015 10:53
-
-
Save rhoot/0f2d7960302bba992e0b to your computer and use it in GitHub Desktop.
Ugly compile-time FNV-1a string hasher
This file contains 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
// --- | |
// Copyright (c) 2015 Johan Sköld | |
// License: https://opensource.org/licenses/ISC | |
// --- | |
#include <cstdint> | |
#include <cstdio> | |
#pragma warning(push) | |
#pragma warning(disable: 4307) // 'operator' : integral constant overflow | |
template <class T, T H, char... Cs> | |
struct ExplodeHasher { | |
static const T HASH = H; | |
}; | |
template <uint32_t H, char C, char... Cs> | |
struct ExplodeHasher<uint32_t, H, C, Cs...> { | |
static const uint32_t HASH = C ? ExplodeHasher<uint32_t, (H ^ C) * 0x1000193, Cs...>::HASH : H; | |
}; | |
template <uint64_t H, char C, char... Cs> | |
struct ExplodeHasher<uint64_t, H, C, Cs...> { | |
static const uint64_t HASH = C ? ExplodeHasher<uint64_t, (H ^ C) * 0x100000001b3, Cs...>::HASH : H; | |
}; | |
#pragma warning(pop) | |
#define E(s, i) (i < sizeof(s) ? s[i] : 0) | |
#define HASH(s, t, h) ExplodeHasher<t, h, E(s, 0x00), E(s, 0x01), E(s, 0x02), E(s, 0x03), E(s, 0x04), E(s, 0x05), E(s, 0x06), E(s, 0x07), \ | |
E(s, 0x08), E(s, 0x09), E(s, 0x0a), E(s, 0x0b), E(s, 0x0c), E(s, 0x0d), E(s, 0x0e), E(s, 0x0f), \ | |
E(s, 0x10), E(s, 0x11), E(s, 0x12), E(s, 0x13), E(s, 0x14), E(s, 0x15), E(s, 0x16), E(s, 0x17), \ | |
E(s, 0x18), E(s, 0x19), E(s, 0x1a), E(s, 0x1b), E(s, 0x1c), E(s, 0x1d), E(s, 0x1e), E(s, 0x1f), \ | |
E(s, 0x20), E(s, 0x21), E(s, 0x22), E(s, 0x23), E(s, 0x24), E(s, 0x25), E(s, 0x26), E(s, 0x27), \ | |
E(s, 0x28), E(s, 0x29), E(s, 0x2a), E(s, 0x2b), E(s, 0x2c), E(s, 0x2d), E(s, 0x2e), E(s, 0x2f), \ | |
E(s, 0x30), E(s, 0x31), E(s, 0x32), E(s, 0x33), E(s, 0x34), E(s, 0x35), E(s, 0x36), E(s, 0x37), \ | |
E(s, 0x38), E(s, 0x39), E(s, 0x3a), E(s, 0x3b), E(s, 0x3c), E(s, 0x3d), E(s, 0x3e), E(s, 0x3f), \ | |
E(s, 0x40), E(s, 0x41), E(s, 0x42), E(s, 0x43), E(s, 0x44), E(s, 0x45), E(s, 0x46), E(s, 0x47), \ | |
E(s, 0x48), E(s, 0x49), E(s, 0x4a), E(s, 0x4b), E(s, 0x4c), E(s, 0x4d), E(s, 0x4e), E(s, 0x4f), \ | |
E(s, 0x50), E(s, 0x51), E(s, 0x52), E(s, 0x53), E(s, 0x54), E(s, 0x55), E(s, 0x56), E(s, 0x57), \ | |
E(s, 0x58), E(s, 0x59), E(s, 0x5a), E(s, 0x5b), E(s, 0x5c), E(s, 0x5d), E(s, 0x5e), E(s, 0x5f), \ | |
E(s, 0x60), E(s, 0x61), E(s, 0x62), E(s, 0x63), E(s, 0x64), E(s, 0x65), E(s, 0x66), E(s, 0x67), \ | |
E(s, 0x68), E(s, 0x69), E(s, 0x6a), E(s, 0x6b), E(s, 0x6c), E(s, 0x6d), E(s, 0x6e), E(s, 0x6f), \ | |
E(s, 0x70), E(s, 0x71), E(s, 0x72), E(s, 0x73), E(s, 0x74), E(s, 0x75), E(s, 0x76), E(s, 0x77), \ | |
E(s, 0x78), E(s, 0x79), E(s, 0x7a), E(s, 0x7b), E(s, 0x7c), E(s, 0x7d), E(s, 0x7e), E(s, 0x7f), \ | |
E(s, 0x80), E(s, 0x81), E(s, 0x82), E(s, 0x83), E(s, 0x84), E(s, 0x85), E(s, 0x86), E(s, 0x87), \ | |
E(s, 0x88), E(s, 0x89), E(s, 0x8a), E(s, 0x8b), E(s, 0x8c), E(s, 0x8d), E(s, 0x8e), E(s, 0x8f), \ | |
E(s, 0x90), E(s, 0x91), E(s, 0x92), E(s, 0x93), E(s, 0x94), E(s, 0x95), E(s, 0x96), E(s, 0x97), \ | |
E(s, 0x98), E(s, 0x99), E(s, 0x9a), E(s, 0x9b), E(s, 0x9c), E(s, 0x9d), E(s, 0x9e), E(s, 0x9f), \ | |
E(s, 0xa0), E(s, 0xa1), E(s, 0xa2), E(s, 0xa3), E(s, 0xa4), E(s, 0xa5), E(s, 0xa6), E(s, 0xa7), \ | |
E(s, 0xa8), E(s, 0xa9), E(s, 0xaa), E(s, 0xab), E(s, 0xac), E(s, 0xad), E(s, 0xae), E(s, 0xaf), \ | |
E(s, 0xb0), E(s, 0xb1), E(s, 0xb2), E(s, 0xb3), E(s, 0xb4), E(s, 0xb5), E(s, 0xb6), E(s, 0xb7), \ | |
E(s, 0xb8), E(s, 0xb9), E(s, 0xba), E(s, 0xbb), E(s, 0xbc), E(s, 0xbd), E(s, 0xbe), E(s, 0xbf), \ | |
E(s, 0xc0), E(s, 0xc1), E(s, 0xc2), E(s, 0xc3), E(s, 0xc4), E(s, 0xc5), E(s, 0xc6), E(s, 0xc7), \ | |
E(s, 0xc8), E(s, 0xc9), E(s, 0xca), E(s, 0xcb), E(s, 0xcc), E(s, 0xcd), E(s, 0xce), E(s, 0xcf), \ | |
E(s, 0xd0), E(s, 0xd1), E(s, 0xd2), E(s, 0xd3), E(s, 0xd4), E(s, 0xd5), E(s, 0xd6), E(s, 0xd7), \ | |
E(s, 0xd8), E(s, 0xd9), E(s, 0xda), E(s, 0xdb), E(s, 0xdc), E(s, 0xdd), E(s, 0xde), E(s, 0xdf), \ | |
E(s, 0xe0), E(s, 0xe1), E(s, 0xe2), E(s, 0xe3), E(s, 0xe4), E(s, 0xe5), E(s, 0xe6), E(s, 0xe7), \ | |
E(s, 0xe8), E(s, 0xe9), E(s, 0xea), E(s, 0xeb), E(s, 0xec), E(s, 0xed), E(s, 0xee), E(s, 0xef), \ | |
E(s, 0xf0), E(s, 0xf1), E(s, 0xf2), E(s, 0xf3), E(s, 0xf4), E(s, 0xf5), E(s, 0xf6), E(s, 0xf7), \ | |
E(s, 0xf8), E(s, 0xf9), E(s, 0xfa), E(s, 0xfb), E(s, 0xfc), E(s, 0xfd), E(s, 0xfe), E(s, 0xff)>::HASH | |
#define HASH32(s) HASH(s, uint32_t, 0x811C9DC5) | |
#define HASH64(s) HASH(s, uint64_t, 0xCBF29CE484222325) | |
int main(int argc, char** argv) { | |
constexpr const char str[] = "D5zari4zxeMecsqTng9L2uGR2al46rMH6xDwMcILPBC13N08j9VVu54D9K3a2xr05keI38K6VPbGN65abFV9Hfr4Hfn8p9C2f80kHvfO7LnhkRHuED5UC2uWHmo3lbQzJAzYkyDX7xx6ZOCOqUAQCDialHx5n9nYJvHoDoMIb4GYDD9pxkz3f3XrrxTzDBZvCnn5W5lHNXv7iXbTfAvmgtwQfpZjfNI1uNVYqt4ptrHOXYTS8Bi3YZN9aqM7WDVG"; | |
printf("Hashing:\n%s\n\n", str); | |
const auto hash32 = HASH32(str); | |
static_assert(hash32 == 0x47dfc4e2, "bad 32-bit hash"); | |
printf("32-bit: %#x\n", hash32); | |
const auto hash64 = HASH64(str); | |
static_assert(hash64 == 0xfe7ec65a9dd699e2, "bad 64-bit hash"); | |
printf("64-bit: %#llx\n", hash64); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment