Skip to content

Instantly share code, notes, and snippets.

@garettbass
Last active May 30, 2019 18:26
Show Gist options
  • Save garettbass/e6ad7030c73c7121a2679a75998385fd to your computer and use it in GitHub Desktop.
Save garettbass/e6ad7030c73c7121a2679a75998385fd to your computer and use it in GitHub Desktop.
Compile time fnv1a 32- and 64-bit hashing of up to 15 characters in C
#pragma once
//------------------------------------------------------------------------------
#define FNV1A32_BASIS (2166136261u)
#define FNV1A32_PRIME (16777619u)
#define FNV1A64_BASIS (14695981039346656037ull)
#define FNV1A64_PRIME (1099511628211ull)
//------------------------------------------------------------------------------
#define static_hash_assert(expr, msg) ((void)!sizeof(char[(expr)?1:-1]))
//------------------------------------------------------------------------------
#define static_hash32(string) (\
(void)static_hash_assert(sizeof(string) <= 16, "string must be 15 or fewer characters"),\
/* string is padded with 16 zeros to ensure 15 accessible characters */\
_static_hash32_0(FNV1A32_BASIS, (string"\0\0\0\0""\0\0\0\0""\0\0\0\0""\0\0\0\0"))\
)
#define _static_hash32_0(hash, str)\
_static_hash32_1((hash ^ 0[str]) * (0[str] ? FNV1A32_PRIME : 1), str)
#define _static_hash32_1(hash, str)\
_static_hash32_2((hash ^ 1[str]) * (1[str] ? FNV1A32_PRIME : 1), str)
#define _static_hash32_2(hash, str)\
_static_hash32_3((hash ^ 2[str]) * (2[str] ? FNV1A32_PRIME : 1), str)
#define _static_hash32_3(hash, str)\
_static_hash32_4((hash ^ 3[str]) * (3[str] ? FNV1A32_PRIME : 1), str)
#define _static_hash32_4(hash, str)\
_static_hash32_5((hash ^ 4[str]) * (4[str] ? FNV1A32_PRIME : 1), str)
#define _static_hash32_5(hash, str)\
_static_hash32_6((hash ^ 5[str]) * (5[str] ? FNV1A32_PRIME : 1), str)
#define _static_hash32_6(hash, str)\
_static_hash32_7((hash ^ 6[str]) * (6[str] ? FNV1A32_PRIME : 1), str)
#define _static_hash32_7(hash, str)\
_static_hash32_8((hash ^ 7[str]) * (7[str] ? FNV1A32_PRIME : 1), str)
#define _static_hash32_8(hash, str)\
_static_hash32_9((hash ^ 8[str]) * (8[str] ? FNV1A32_PRIME : 1), str)
#define _static_hash32_9(hash, str)\
_static_hash32_10((hash ^ 9[str]) * (9[str] ? FNV1A32_PRIME : 1), str)
#define _static_hash32_10(hash, str)\
_static_hash32_11((hash ^ 10[str]) * (10[str] ? FNV1A32_PRIME : 1), str)
#define _static_hash32_11(hash, str)\
_static_hash32_12((hash ^ 11[str]) * (11[str] ? FNV1A32_PRIME : 1), str)
#define _static_hash32_12(hash, str)\
_static_hash32_13((hash ^ 12[str]) * (12[str] ? FNV1A32_PRIME : 1), str)
#define _static_hash32_13(hash, str)\
_static_hash32_14((hash ^ 13[str]) * (13[str] ? FNV1A32_PRIME : 1), str)
#define _static_hash32_14(hash, str)\
_static_hash32_15((hash ^ 14[str]) * (14[str] ? FNV1A32_PRIME : 1), str)
#define _static_hash32_15(hash, str)\
((hash ^ 15[str]) * (15[str] ? FNV1A32_PRIME : 1))
//------------------------------------------------------------------------------
#define static_hash64(string) (\
(void)static_hash_assert(sizeof(string) <= 16, "string must be 15 or fewer characters"),\
/* string is padded with 16 zeros to ensure 15 accessible characters */\
_static_hash64_0(FNV1A64_BASIS, (string"\0\0\0\0""\0\0\0\0""\0\0\0\0""\0\0\0\0"))\
)
#define _static_hash64_0(hash, str)\
_static_hash64_1((hash ^ 0[str]) * (0[str] ? FNV1A64_PRIME : 1), str)
#define _static_hash64_1(hash, str)\
_static_hash64_2((hash ^ 1[str]) * (1[str] ? FNV1A64_PRIME : 1), str)
#define _static_hash64_2(hash, str)\
_static_hash64_3((hash ^ 2[str]) * (2[str] ? FNV1A64_PRIME : 1), str)
#define _static_hash64_3(hash, str)\
_static_hash64_4((hash ^ 3[str]) * (3[str] ? FNV1A64_PRIME : 1), str)
#define _static_hash64_4(hash, str)\
_static_hash64_5((hash ^ 4[str]) * (4[str] ? FNV1A64_PRIME : 1), str)
#define _static_hash64_5(hash, str)\
_static_hash64_6((hash ^ 5[str]) * (5[str] ? FNV1A64_PRIME : 1), str)
#define _static_hash64_6(hash, str)\
_static_hash64_7((hash ^ 6[str]) * (6[str] ? FNV1A64_PRIME : 1), str)
#define _static_hash64_7(hash, str)\
_static_hash64_8((hash ^ 7[str]) * (7[str] ? FNV1A64_PRIME : 1), str)
#define _static_hash64_8(hash, str)\
_static_hash64_9((hash ^ 8[str]) * (8[str] ? FNV1A64_PRIME : 1), str)
#define _static_hash64_9(hash, str)\
_static_hash64_10((hash ^ 9[str]) * (9[str] ? FNV1A64_PRIME : 1), str)
#define _static_hash64_10(hash, str)\
_static_hash64_11((hash ^ 10[str]) * (10[str] ? FNV1A64_PRIME : 1), str)
#define _static_hash64_11(hash, str)\
_static_hash64_12((hash ^ 11[str]) * (11[str] ? FNV1A64_PRIME : 1), str)
#define _static_hash64_12(hash, str)\
_static_hash64_13((hash ^ 12[str]) * (12[str] ? FNV1A64_PRIME : 1), str)
#define _static_hash64_13(hash, str)\
_static_hash64_14((hash ^ 13[str]) * (13[str] ? FNV1A64_PRIME : 1), str)
#define _static_hash64_14(hash, str)\
_static_hash64_15((hash ^ 14[str]) * (14[str] ? FNV1A64_PRIME : 1), str)
#define _static_hash64_15(hash, str)\
((hash ^ 15[str]) * (15[str] ? FNV1A64_PRIME : 1))
//------------------------------------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment