
Hash 32 C
It's the fastest 32-bit, OAAT hashing algorithm versus GoodOAAT and Jenkins' OAAT.
Algorithm
Source
#include <stdint.h>
uint32_t eightomic_hash_32_c(const unsigned long input_count,
const uint8_t *input) {
uint32_t mix = 1;
uint32_t mix_offset = 1111111111;
unsigned long i = 0;
while (i < input_count) {
mix += input[i];
mix += mix << 3;
mix_offset += mix + mix_offset;
mix_offset = (mix_offset << 19) | (mix_offset >> 13);
i++;
}
mix ^= mix_offset;
mix += (mix_offset << 27) | (mix_offset >> 5);
mix_offset ^= mix >> 4;
mix += (mix_offset << 8) | (mix_offset >> 24);
mix ^= mix_offset >> 3;
mix_offset += (mix << 14) | (mix >> 18);
mix_offset ^= ((mix << 9) | (mix >> 23)) + (mix_offset >> 7);
return mix ^ mix_offset;
}
License
It's free and open source.
Reference
eightomic_hash_32_c() is the hashing function that accepts the following 2 arguments in left-to-right order.
1: input_count is the const unsigned long count of elements in the input array.
2: input is the const uint8_t array to hash.
The return value data type is uint32_t.
It returns the 32-bit unsigned integer hash digest result.
Explanation
It's faster than GoodOAAT on average at input sizes segmented from 1 byte to 32 bytes and 1 byte to 64 bytes. It's faster at all input sizes greater than 64 bytes.
It's faster than Jenkins' OAAT at all input sizes.
It passes all seedless SMHasher tests.
Auxiliary seed input isn't a strict requirement for non-cryptographic hashing algorithms, but Eightomic is developing and testing an improved version that accepts a 32-bit seed integer when implementations require it.
It appears similar to GoodOAAT due to the limited options when designing the fastest one-at-a-time hashing function with good diffusion and collision avoidance, but the technical difference is vast.
The first expression is indentical. It adds an input byte to mix before combining with mix_offset.
The second expression is identical. Any bitwise multiplication with a left shift operand greater than << 3 is too slow in the core hashing loop and anything less doesn't result in enough distribution to omit a second bitwise multiplication.
It left-rotates bits in mix_offset after additive assignment instead of right-rotating bits in mix before additive assignment.
mix_offset combines with mix summed with an additional mix_offset as a cheap addition operand instead of a slow bitwise multiplication after the bit rotation.
Furthermore, the bit rotation is non-blocking with instruction-level parallelism for each next byte iteration.
The speed gains from these design differences allow for Xorshift operations in the finalization sequence to create a greater avalanche effect.