CPlay/fnv1a.c
2025-12-27 07:10:09 +01:00

60 lines
1.4 KiB
C

/*
* Check wikipedia for details and pseudocode.
*/
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#define FNV1A64_BASIS 0XCBF29CE484222325
#define FNV1A64_PRIME 0X00000100000001B3
uint64_t fnv1a64(const char *data, size_t len) {
uint64_t hash = FNV1A64_BASIS;
for (size_t i = 0; i < len; i++) {
hash = (hash ^ (uint64_t)data[i]) * FNV1A64_PRIME;
}
return hash;
}
#define FNV1A32_BASIS 0x811c9dc5
#define FNV1A32_PRIME 0x01000193
uint32_t fnv1a32(const char *data, size_t len) {
uint32_t hash = FNV1A32_BASIS;
for (size_t i = 0; i < len; i++) {
hash = (hash ^ (uint32_t)data[i]) * FNV1A32_PRIME;
}
return hash;
}
int main(void) {
char *str = "hello\0";
uint64_t h64 = fnv1a64(str, strnlen(str, 128));
uint32_t h32 = fnv1a32(str, strnlen(str, 128));
char *str_2 = "Hello\0";
uint64_t h64_2 = fnv1a64(str_2, strnlen(str, 128));
uint32_t h32_2 = fnv1a32(str_2, strnlen(str, 128));
printf("FNV1a64 of \"hello\": %lX\n", h64);
printf("FNV1a32 of \"hello\": %X\n", h32);
printf("FNV1a64 of \"Hello\": %lX\n", h64_2);
printf("FNV1a32 of \"Hello\": %X\n", h32_2);
fflush(stdin);
assert(h64 == 0xA430D84680AABD0B);
assert(h32 == 0x4F9F2CAB);
assert(h64_2 == 0x63F0BFACF2C00F6B);
assert(h32_2 == 0xF55C314B);
printf("All tests passed!\n");
}