Skip to content

Instantly share code, notes, and snippets.

@skeeto
Created October 15, 2021 11:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skeeto/3c91495daaa5e91a52c03dd1b6033f6a to your computer and use it in GitHub Desktop.
Save skeeto/3c91495daaa5e91a52c03dd1b6033f6a to your computer and use it in GitHub Desktop.
Hash function collision test
// Hash function collision test
// * https://www.andreinc.net/2021/10/02/implementing-hash-tables-in-c-part-1
// * https://redd.it/q88m49
// This is free and unencumbered software released into the public domain.
#include <stdint.h>
#include <stdio.h>
#define INIT 5381
#define MULT 33
uint32_t hashf_djb2(char *str)
{
uint32_t hash = INIT;
char c;
while ((c = *str++)) {
hash = ((hash << 5) + hash) + c;
}
return hash;
}
uint32_t hashf_djb2_m(char *str)
{
uint32_t hash = INIT;
char c;
while ((c = *str++)) {
hash = hash * MULT + c;
}
return hash;
}
uint32_t hashf_sdbm(char *str)
{
uint32_t hash = 0;
char c;
while ((c = *str++)) {
hash = c + (hash << 6) + (hash << 16) - hash;
}
return hash;
}
uint32_t finalizer(uint32_t h)
{
h ^= h >> 16;
h *= 0x3243f6a9U;
h ^= h >> 16;
return h;
}
int test(uint32_t (*f)(char *), _Bool finalize)
{
int collisions = 0;
char seen[1<<14] = {0};
for (int i = 0; i < 10000; i++) {
char buf[16];
snprintf(buf, sizeof(buf), "%d", i);
uint32_t h = f(buf);
if (finalize) {
h = finalizer(h);
}
h %= sizeof(seen);
if (seen[h]) {
collisions++;
}
seen[h] = 1;
}
return collisions;
}
int main(void)
{
printf(" collisions finalized\n");
printf("djb2 %10d%10d\n", test(hashf_djb2, 0), test(hashf_djb2, 1));
printf("djb2_m %10d%10d\n", test(hashf_djb2_m, 0), test(hashf_djb2_m, 1));
printf("sdbm %10d%10d\n", test(hashf_sdbm, 0), test(hashf_sdbm, 1));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment