Skip to content

Instantly share code, notes, and snippets.

@rhoot
Created December 18, 2015 10:53
Show Gist options
  • Save rhoot/0f2d7960302bba992e0b to your computer and use it in GitHub Desktop.
Save rhoot/0f2d7960302bba992e0b to your computer and use it in GitHub Desktop.
Ugly compile-time FNV-1a string hasher
// ---
// 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