2025-04-09
I was fiddling, as you do, in C and came up with this. It doesn’t suck too much according to Smhasher, at least when you compare it to functions of similar complexity.
It is surely not good enough for cryptography, but it’s an okay function. And I am satisfied with what became of my afternoon.
uint64_t SillyHash(const void* key, int len, uint64_t seed) {
uint64_t hash = seed;
uint64_t fib = 0x1525454544AA2A45;
for (uint64_t i = 0; i < len; i++) {
uint64_t α = ((unsigned char*) key)[i];
*= ((fib >> (i % 64)) | (fib << (64 - (i % 64))));
α ^= ((fib << (i % 64)) | (fib >> (64 - (i % 64))));
hash *= ((fib >> (i % 64)) | (fib << (64 - (i % 64))));
hash ^= ((hash >> 9) | (hash << (64 - 9))) + α;
hash }
^= seed;
hash = ~hash + (hash << 36);
hash ^= hash ^ ((hash >> 59) | (hash << (64 - 59)));
hash *= fib;
hash ^= hash ^ ((hash >> 13) | (hash << (64 - 13)));
hash *= fib;
hash ^= ((hash >> 53) | (hash << (64 - 53)));
hash += seed;
hash
return hash;
}
The magical constant is just an irregular bit pattern I got from the following:
1
11
21
1211
111221
312211
13112221
1113213211
31131211131221
13211311123113112211
0x1525454544AA2A45
= 0001 0101 0010 0101 0100 0101 0100 0101 0100 0100 1010 1010 0010 1010 0100 0101
| | | | | | | | | | | | | | | | | | | | | | |
1 1 2 2 1 1 3 1 1 3 1 1 3 2 1 1 1 3 1 1 2 3 1
Which is to say, the intervals between set bits correspond to the numbers of the sequence I’ve described. It came to me sort of by accident that I wanted to mix the bits by doing operations with rotations and I wanted a pattern that was sufficiently dense but also not predictably periodical in any obvious way.
It is capable of producing 541.32 MiB/sec @ 3000 MHz.
It is available under the Goudet Public License v0, or GPLv3-or-later or MIT.