diff --git a/src/lastguest/Murmur.php b/src/lastguest/Murmur.php index deef5ca..9c84119 100644 --- a/src/lastguest/Murmur.php +++ b/src/lastguest/Murmur.php @@ -14,48 +14,61 @@ namespace lastguest; -class Murmur { +class Murmur +{ /** * @param string $key Text to hash. * @param integer $seed Positive integer only * @return integer 32-bit positive integer hash */ - public static function hash3_int(string $key, int $seed=0) : int { - $key = array_values(unpack('C*', $key)); + public static function hash3_int(string $key, int $seed = 0): int + { + $key = array_values(unpack('C*', $key)); $klen = count($key); - $h1 = $seed < 0 ? -$seed : $seed; - $remainder = $i = 0; - for ($bytes=$klen-($remainder=$klen&3) ; $i < $bytes ; ) { - $k1 = $key[$i] - | ($key[++$i] << 8) - | ($key[++$i] << 16) - | ($key[++$i] << 24); + $h1 = $seed < 0 ? -$seed : $seed; + $bytes = $klen - ($remainder = $klen & 3); + + for ($i = 0; $i < $bytes; ) { + $k1 = $key[$i] | + ($key[++$i] << 8) | + ($key[++$i] << 16) | + ($key[++$i] << 24); ++$i; - $k1 = (((($k1 & 0xffff) * 0xcc9e2d51) + ((((($k1 >= 0 ? $k1 >> 16 : (($k1 & 0x7fffffff) >> 16) | 0x8000)) * 0xcc9e2d51) & 0xffff) << 16))) & 0xffffffff; - $k1 = $k1 << 15 | ($k1 >= 0 ? $k1 >> 17 : (($k1 & 0x7fffffff) >> 17) | 0x4000); - $k1 = (((($k1 & 0xffff) * 0x1b873593) + ((((($k1 >= 0 ? $k1 >> 16 : (($k1 & 0x7fffffff) >> 16) | 0x8000)) * 0x1b873593) & 0xffff) << 16))) & 0xffffffff; + + $k1 = (($k1 & 0xFFFF) * 0x2D51 + ((($k1 >> 16) * 0x2D51 + ($k1 & 0xFFFF) * 0xCC9E) << 16)) & 0xFFFFFFFF; + $k1 = (($k1 << 15) | (($k1 >> 17) & 0x7FFF)) & 0xFFFFFFFF; + $k1 = (($k1 & 0xFFFF) * 0x3593 + ((($k1 >> 16) * 0x3593 + ($k1 & 0xFFFF) * 0x1B87) << 16)) & 0xFFFFFFFF; + $h1 ^= $k1; - $h1 = $h1 << 13 | ($h1 >= 0 ? $h1 >> 19 : (($h1 & 0x7fffffff) >> 19) | 0x1000); - $h1b = (((($h1 & 0xffff) * 5) + ((((($h1 >= 0 ? $h1 >> 16 : (($h1 & 0x7fffffff) >> 16) | 0x8000)) * 5) & 0xffff) << 16))) & 0xffffffff; - $h1 = ((($h1b & 0xffff) + 0x6b64) + ((((($h1b >= 0 ? $h1b >> 16 : (($h1b & 0x7fffffff) >> 16) | 0x8000)) + 0xe654) & 0xffff) << 16)); + $h1 = (($h1 << 13) | (($h1 >> 19) & 0x1FFF)) & 0xFFFFFFFF; + $h1 = (($h1 & 0xFFFF) * 5 + ((($h1 >> 16) * 5) << 16)) & 0xFFFFFFFF; + $h1 = ($h1 + 0xe6546b64) & 0xFFFFFFFF; } - $k1 = 0; - switch ($remainder) { - case 3: $k1 ^= $key[$i + 2] << 16; - case 2: $k1 ^= $key[$i + 1] << 8; - case 1: $k1 ^= $key[$i]; - $k1 = ((($k1 & 0xffff) * 0xcc9e2d51) + ((((($k1 >= 0 ? $k1 >> 16 : (($k1 & 0x7fffffff) >> 16) | 0x8000)) * 0xcc9e2d51) & 0xffff) << 16)) & 0xffffffff; - $k1 = $k1 << 15 | ($k1 >= 0 ? $k1 >> 17 : (($k1 & 0x7fffffff) >> 17) | 0x4000); - $k1 = ((($k1 & 0xffff) * 0x1b873593) + ((((($k1 >= 0 ? $k1 >> 16 : (($k1 & 0x7fffffff) >> 16) | 0x8000)) * 0x1b873593) & 0xffff) << 16)) & 0xffffffff; - $h1 ^= $k1; + + if ($remainder) { + $k1 = 0; + switch ($remainder) { + case 3: + $k1 ^= $key[$i + 2] << 16; + case 2: + $k1 ^= $key[$i + 1] << 8; + case 1: + $k1 ^= $key[$i]; + $k1 = (($k1 & 0xFFFF) * 0x2D51 + ((($k1 >> 16) * 0x2D51 + ($k1 & 0xFFFF) * 0xCC9E) << 16)) & 0xFFFFFFFF; + $k1 = (($k1 << 15) | (($k1 >> 17) & 0x7FFF)) & 0xFFFFFFFF; + $k1 = (($k1 & 0xFFFF) * 0x3593 + ((($k1 >> 16) * 0x3593 + ($k1 & 0xFFFF) * 0x1B87) << 16)) & 0xFFFFFFFF; + $h1 ^= $k1; + } } + $h1 ^= $klen; - $h1 ^= ($h1 >= 0 ? $h1 >> 16 : (($h1 & 0x7fffffff) >> 16) | 0x8000); - $h1 = ((($h1 & 0xffff) * 0x85ebca6b) + ((((($h1 >= 0 ? $h1 >> 16 : (($h1 & 0x7fffffff) >> 16) | 0x8000)) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff; - $h1 ^= ($h1 >= 0 ? $h1 >> 13 : (($h1 & 0x7fffffff) >> 13) | 0x40000); - $h1 = (((($h1 & 0xffff) * 0xc2b2ae35) + ((((($h1 >= 0 ? $h1 >> 16 : (($h1 & 0x7fffffff) >> 16) | 0x8000)) * 0xc2b2ae35) & 0xffff) << 16))) & 0xffffffff; - $h1 ^= ($h1 >= 0 ? $h1 >> 16 : (($h1 & 0x7fffffff) >> 16) | 0x8000); + $h1 ^= ($h1 >> 16) & 0xFFFF; + $h1 = (($h1 & 0xFFFF) * 0xCA6B + ((($h1 >> 16) * 0xCA6B + ($h1 & 0xFFFF) * 0x85EB) << 16)) & 0xFFFFFFFF; + $h1 ^= ($h1 >> 13) & 0x7FFFF; + $h1 = (($h1 & 0xFFFF) * 0xAE35 + ((($h1 >> 16) * 0xAE35 + ($h1 & 0xFFFF) * 0xC2B2) << 16)) & 0xFFFFFFFF; + $h1 ^= ($h1 >> 16) & 0xFFFF; + return $h1; } @@ -64,7 +77,8 @@ public static function hash3_int(string $key, int $seed=0) : int { * @param integer $seed Positive integer only * @return string */ - public static function hash3(string $key, int $seed=0) : string { + public static function hash3(string $key, int $seed = 0): string + { return base_convert(sprintf("%u\n", self::hash3_int($key, $seed)), 10, 32); } }