diff --git a/src/hash.c b/src/hash.c index 1dba928be..060bcb3c3 100644 --- a/src/hash.c +++ b/src/hash.c @@ -361,7 +361,10 @@ mrb_obj_hash_code(mrb_state *mrb, mrb_value key) hash_code = U32(tt) ^ U32(mrb_integer(hash_code_obj)); break; } - return hash_code ^ (hash_code << 2) ^ (hash_code >> 2); + hash_code ^= hash_code >> 16; + hash_code *= 0x45d9f3b; + hash_code ^= hash_code >> 16; + return hash_code; } static uint32_t diff --git a/src/string.c b/src/string.c index d490ec310..851a42f47 100644 --- a/src/string.c +++ b/src/string.c @@ -2014,18 +2014,18 @@ mrb_byte_hash_step(const uint8_t *s, mrb_int len, uint32_t hval) const uint8_t *send = s + len; /* - * FNV-1 hash each octet in the buffer + * FNV-1a hash each octet in the buffer */ while (s < send) { + /* xor the bottom with the current octet */ + hval ^= (uint32_t)*s++; + /* multiply by the 32-bit FNV magic prime mod 2^32 */ #if defined(NO_FNV_GCC_OPTIMIZATION) hval *= FNV_32_PRIME; #else hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); #endif - - /* xor the bottom with the current octet */ - hval ^= (uint32_t)*s++; } /* return our new hash value */