Skip to content

Instantly share code, notes, and snippets.

@cshenton
Created November 24, 2025 11:10
Show Gist options
  • Select an option

  • Save cshenton/32b1609fea95bc55aa7ebf382e5972a3 to your computer and use it in GitHub Desktop.

Select an option

Save cshenton/32b1609fea95bc55aa7ebf382e5972a3 to your computer and use it in GitHub Desktop.
#include <stdint.h>
// Firefox hash or "fxhash". Prefer len to be a compile-time multiple of 8. Zero pad input if necessary.
// This is a rubbish hash function. I just wanted to implement it.
uint64_t fxhash(const uint8_t* s, uint64_t len)
{
const uint32_t ROTATE = 5;
const uint64_t SEED = 0x517CC1B727220A95ULL;
uint64_t state = 0;
uint64_t iter = len >> 3;
uint64_t rem = len & 0x7;
for (uint64_t i=0; i<=iter; i++) {
uint64_t word = 0;
__builtin_memcpy(&word, s + 8*i, 8);
state = (state << ROTATE) | (state >> (64 - ROTATE));
state = state ^ word;
state = state * SEED;
}
if (rem > 0) {
uint64_t word = 0;
const uint8_t *q = s + 8*iter;
switch (rem) {
case 7: { word |= (uint64_t)q[6] << 48; }
case 6: { word |= (uint64_t)q[5] << 40; }
case 5: { word |= (uint64_t)q[4] << 32; }
case 4: { word |= (uint64_t)q[3] << 24; }
case 3: { word |= (uint64_t)q[2] << 16; }
case 2: { word |= (uint64_t)q[1] << 8; }
case 1: { word |= (uint64_t)q[0]; }
default: break;
}
state = (state << ROTATE) | (state >> (64 - ROTATE));
state = state ^ word;
state = state * SEED;
}
return state;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment