use constant A => 0; use constant B => 1; use constant C => 2; sub mix ($$$) { use integer; $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] ^= ($_[C]>>13); $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] ^= ($_[A]<< 8); $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] ^= ($_[B]>>13); $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] ^= ($_[C]>>12); $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] ^= ($_[A]<<16); $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] ^= ($_[B]>> 5); $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] ^= ($_[C]>> 3); $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] ^= ($_[A]<<10); $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] ^= ($_[B]>>15); } use constant GOLDEN_RATIO => 0x9e3779b9; use constant INITHASH => 2; sub hash { use integer; my($a,$b,$c) = (GOLDEN_RATIO, GOLDEN_RATIO, $_[INITHASH]); my ($p, $len) = (0, length $_[KEY]); do { my($x,$y,$z) = unpack 'V3', substr($_[KEY] . (chr(0)x11), $p, 12); mix($a += $x, $b += $y, $c += $z + $len); $p+=12; } while $p <= $len; return $c; }