in reply to Pure perl Jenkins 32 bit Hash

As mentioned in the OP i needed a 32bit hash and searched around. I decided id show how i ended up at my solution as well.

At the bottom of this post are 4 source files. Assume the perl program is called hashtest1.pl

When i found Re: Fast string hash in portable perl? [DO NOT USE!] i decided to try it. I was rather dismayed, Jenkins was supposed to be better than this. (Hits represents the number of filenames in the bucket. )

To start, i first ran perl hashtest1.pl  -file bigtest  -dir d:/ so as not to reburden myself with a find of 110405 files over and over. (ok, in the beginning i did, the file read/write code did come later, just pretend for now).

perl hashtest1.pl -file bigtest -seed 0 -hash orig Hashed:110405 hits n 0 4294856890 1 91335 2 3018 3 1028 4 386 5 184 6 218 7 52 8 70 9 169 10 141 11 5 12 12 13 8 14 7 15 2 16 1 18 5 19 2 20 9 28 3 29 1 30 15 31 26 88 1 111 1
So i went back to the Jenkins source. I was concerned about $z||='0'; $z<<=8; and decided to try the network order in unpack, and '0' became just 0 in case the shift was shifting the char 0.
D:\active\misc\util>perl hashtest1.pl -file bigtest -seed 0 -hash ha +sh2 Hashed:110405 hits n 0 4294856890 1 105501 2 1222 3 156 4 119 5 28 6 29 7 27 8 14 9 20 10 10 11 3 12 15 13 2 14 3 17 3 18 6 20 1 21 3 22 3 32 1
Better but not enough. And a little endian version perl hashtest1.pl  -file bigtest  -seed 0 -hash orig  -h2 hash20 showed that it was shifting the numeric zero.

Maybe it was just the seed. Nope.

perl hashtest1.pl -file bigtest -seed 1 -hash orig Hashed:110405 hits n 0 4294856890 1 86318 2 2019 3 715 4 276 5 178 6 212 7 110 8 105 9 204 10 168 11 51 12 96 13 25 14 27 15 47 16 19 17 34 18 41 19 4 20 18 21 16 22 4 23 17 24 3 26 2 27 2 31 1 36 3 38 1 39 1 40 1 46 1 47 1 49 1 61 1 68 1 69 1 95 1 103 1 116 1 120 1 122 1 198 1 224 1 226 1 251 1 415 1 423 1 453 1

So i duplicated lookup2.c better perl hashtest1.pl  -file bigtest  -seed 0 -hash hash3, but the result wasnt any better at all.

So i looked closer, and realized that while "use integer" was in effect for hash, it was not in mix. So i made new versions that used integer math everywhere.

perl hashtest1.pl -file bigtest -seed 0 -hash hashi hits n 0 4294856890 1 110403 2 1
Much better, but by now i realized the $z||=0 and  $z<<=8 stuff was all wrong.
perl hashtest1.pl -file bigtest -seed 0 -hash hash3i differences:110405 hits n 0 4294856890 1 110403 2 1
And i was running a 64bit arch and needed the revised code.
perl hashtest1.pl -file bigtest -seed 0 -hash hash30 -h2 hashi Hashed:110405 hits n 0 4294856890 1 110403 2 1

But in looking close realized Jenkins had a mistake, the first line of the revised mix could shift in a one rather than zero if c overflowed 32 bits from the char additions.

perl hashtest1.pl -file bigtest -seed 0 -hash hash3a perl hashtest1.pl -file bigtest -seed 0 -hash hash3f perl hashtest1.pl -file bigtest -seed 0 -hash hash3f2 perl hashtest1.pl -file bigtest -seed 0 -hash hash3f3 perl hashtest1.pl -file bigtest -seed 0 -hash hash38
These are all just transforms of each other, and i settled on hash38 (also called fix) as my replacement.

I thought i was happy, and had faithfully represented the lookup2.c code. I was going to stop there, luckily i didnt. I wanted to compare my hashs with those from lookup2.c. I decided to try Digest::JHash.

perl hashtest1.pl -file bigtest -seed 0 -hash fish -h2 fix differences:23 Hashed:110405 hits n 0 4294856890 1 110405
Wait differences? What did i do wrong? So i dug up the code and looked close. (i was happy to see they used the same final form i did for the arch64 fix.) First i wanted to know where perl hashtest1.pl  -file bigtest  -seed 0 -hash fish -h2 hash38 -listdiff -finddiff, then with a bigger file perl hashtest1.pl  -file d3t.txt  -seed 0 -hash fish -h2 hash38 -listdiff -finddiff i confirmed it was a "extended chars" problem.

I overly debuged my version perl hashtest1.pl  -file d3t.txt  -seed 0 -hash fish -h2 fix  -listdiff -finddiff  -blowup but everything looked right. To dig deeper i needed more tools. Inline::C. While it was more of a pain to install then i expected besides the wall time and prompts it went ok.

I didnt see anything obvious I overly debuged it too. perl hashtest1.pl  -file bigtest  -seed 0  -blowup -hash fishodvs -h2 fixexp and the problem jumped out, after adding in the 4 chars they had 9e37631a in a while i had 9e38631a. i added more debug and realized for what is called z in the perl they had ffffe961 while i had 0000e961. It took me a while to realize why, I looked an looked for why theirs was negative while mine was positive, played with typecasts, and read more about unsigned ints in C. Then the light came on. I looked at lookup2.c  typedef  unsigned char ub1;register ub1 *k; while in jhash.xs char* p; thinking E9 was negative, in casting it to a U32 it preserved the sign bit and its rightward progression. The character addition turned into a subtraction and they got ffffe961.

Now that i knew, the fix was easy. unsigned char* p; perl hashtest1.pl  -file d3t.txt  -seed 0 -hash fishodvu -h2 fixexp  -listdiff -finddiff  -blowup. yea 0000e961 and 0 differences!!

Even on the big file, 0 differences! perl hashtest1.pl  -file d3t.txt  -seed 0 -hash fishic -h2 fix.

I was happy!.

This is hashtest1.pl
Edit: This is an updated version, in particular the mix4 mentioned at Re: Pure perl Jenkins 32 bit Hash is now called mix4x

# testing 32 bit jenkins hashs use strict; use warnings; $|=1; use File::Find; use Getopt::Long; use Config; if ( $Config{ivsize} == 4 ) { *main::h64=*main::h32; *main::tobit=*main::tobit32; } my $debug =0; my $file =''; my $dir =''; my $hash ='orig'; my $h2 =''; my $printif =0; my $seed =0; my $listdiff=0; my $finddiff=0; my $listall =0; my $blowupfast=0; my $output =''; my $noc =0; my %optdef= ("debug=i" => \$debug ,"file=s" => \$file ,"hash=s" => \$hash ,"h2=s" => \$h2 ,"dir=s" => \$dir ,"printif=i" => \$printif ,"seed=i" => \$seed ,"listdiff" => \$listdiff ,"finddiff" => \$finddiff ,"listall" => \$listall ,"blowupfast" => \$blowupfast ,"output=s" => \$output ,"noc" => \$noc ); GetOptions ( %optdef ) or die("Error in command line arguments"); use Data::Dumper; if ($debug) {print Dumper(\%optdef);} die 'need -dir or -file' unless ($dir || $file ); unless ($noc){ # with -noc cant use -hash fish fishic fishodvs fis +hodvu # http://www.perlmonks +.org/?node_id=151114 # http://cpansearch.pe +rl.org/src/SHLOMIF/Digest-JHash-0.10/JHash.xs { no strict; unless (eval 'use Inline C => "./jhashic.c"; 1' ) {print "no fis +hic\n";} unless (eval 'use Inline C => "./jhashodvs.c";1') {print "no fis +hodvs\n";} unless (eval 'use Inline C => "./jhashodvu.c";1') {print "no fis +hodvu\n";} } # strict unless (eval 'use Digest::JHash;1') {print "no fishodvu\n";} } # noc # some early ranting # print '1N :'.unpack("H*", pack("N", 1))."\n"; # print '1L :'.unpack("H*", pack("L", 1))."\n"; # print '2g :'.unpack("H*", pack("N", 2147483647))."\n"; # print '4g :'.unpack("H*", pack("N", 4294967295))."\n"; # print 'L :'.unpack("H*", pack("L", 0x0a0b0c0d))."\n"; # print 'N :'.unpack("H*", pack("N", 0x0a0b0c0d))."\n"; # print 'H4 :'.unpack("H*", pack("Q", 0x0a0b0c0d))."\n"; # print 'H8 :'.unpack("H*", pack("Q", 0x0a0b0c0d0e0f1a1b))."\n"; #order64('0x0a0b0c0d0e0f1a1b',0x0a0b0c0d0e0f1a1b); if(0) { { use integer; use Devel::Peek; my $a = 2**31 - 1; # Largest positive integer on 32-bit machi +nes my $a1=$a+1; print $a; print ' '.$a+1; print ' '.$a1; printf ' u+ %10u' ,$a+1; printf ' f+ %14f5',$a+1; printf ' u1 %10u' ,$a1; printf ' f1 %14f5',$a1; printf ' h+ '.h64($a+1); printf ' h1 '.h64($a1); print "\n"; Dump($a); Dump($a1); } { no integer; use Devel::Peek; my $a = 2**31 - 1; # Largest positive integer on 32-bit machi +nes my $a1=$a+1; print $a; print ' '.$a+1; print ' '.$a1; printf ' u+ %10u' ,$a+1; printf ' f+ %14f5',$a+1; printf ' u1 %10u' ,$a1; printf ' f1 %14f5',$a1; printf ' h+ '.h64($a+1); printf ' h1 '.h64($a1); print "\n"; Dump($a); Dump($a1); } exit; } # 00000000000 my $list; unless ($blowupfast){ if ($dir) {$list=finder($dir);} if ($dir && $file) { open (my $fh,'>',$file) or die "cant open $file $!"; for my $fn (@$list) { print $fh $fn."\n"; } close ($fh) or die "cant close $file $!"; exit; } else { $list=[]; open (my $fh,'<',$file) or die "cant open $file $!"; while (my $line=<$fh>) { chomp $line; push @$list,$line; } close ($fh) or die "cant close $file $!"; } # file } else { # for testing the "problem" e9 caused a lot of problems, so did +f6 # $list=['a'."\xe9",'ab'."\xe9",'abc'."\xe9",'abcd'."\xe9",'abc +de'."\xe9",'abcdef'."\xe9",'abcdefg'."\xe9",'abcdefgh'."\xe9"]; # $list=['a','ab','abc','abcd','abc'."\xe9",'a'."\xe9",'ab'."\x +e9",'abcd'."\xe9"]; $list=['a'."\xe9"]; } #for my $chr (@$list) { print sprintf('%3d',length($chr)).' '.$chr." +\n"; } exit; my $hashs={}; $hashs->{orig} =\&hash; $hashs->{hash2} =\&hash2; $hashs->{hash20} =\&hash20; $hashs->{hash3} =\&hash3; # $hashs->{hash3exp} =\&hash3exp; $hashs->{hash3ui} =\&hash3ui; $hashs->{origi} =\&hashi; $hashs->{hashi} =\&hashi; $hashs->{hash2i} =\&hash2i; $hashs->{hash3i0} =hash3s(\&mix4x); $hashs->{hash3i} =hash3s(\&mix4); $hashs->{hash30} =hash3s(\&mix80); $hashs->{hash3a} =hash3s(\&mix8a); $hashs->{hash3f} =hash3s(\&mix80f); $hashs->{hash3f2} =hash3s(\&mix80f2); $hashs->{hash3f3} =hash3s(\&mix80f3); $hashs->{hash38} =\&hash38; $hashs->{hash38ni} =hash3s(\&mix8ni); $hashs->{hash3m0} =hash3s(\&mix); $hashs->{hash38exp}=\&hash38exp; $hashs->{fix} =\&hash38; $hashs->{fixexp} =\&hash38exp; $hashs->{fish} =\&hashfish; $hashs->{fishic} =\&hashfishic; $hashs->{fishodvs} =\&hashfishs; $hashs->{fishodvu} =\&hashfishu; $hashs->{hash34} =hash3s(\&mix4); $hashs->{hash34x} =hash3s(\&mix4x); $hashs->{hash3exp} =hash3sexp(\&mixexp ,'mixexp'); $hashs->{hash34exp} =hash3sexp(\&mix4exp,'mix4exp'); my $sub0=$hashs->{$hash}; die "bad hash name $hash" unless ($sub0); my $sub2; if ($h2) { $sub2=$hashs->{$h2}; die "bad hash name $h2" unless ($sub2); } my %space; my %names; my $hashct=scalar(@$list); my $oh; if ($output) { open ($oh,'>',$output) or die "cant open oh $output $!"; print $oh "-seed $seed -hash $hash -h2 $h2\n"; } if ($h2) { # compare mode my $diff=0; my %bad; my %bad4; for my $fn (@$list) { my $hh =&{$sub0}($fn,$seed); my $hh2=&{$sub2}($fn,$seed); if ($output) { print $oh $hh.' '.$hh2.' '.$fn."\n"; } if ($hh2 ne $hh) { $diff++; if ($listdiff) { print $hh.' '.$hh2.' '. +$fn."\n"; if ($h2 eq 'fix') { my $hh2e=&{$hashs->{fixexp}}($fn,$seed); print $hh.' '.$hh2e.' + '.$fn."\n"; } if ($finddiff) { for my $ii (1..length($fn)) { my $sh1=&{$sub0}(substr($fn,0,$ii),$seed); my $sh2=&{$sub2}(substr($fn,0,$ii),$seed); if ($sh1 ne $sh2) { print $hh.' '.$hh2.' + '.$fn."\n"; print 'ahah:'.sprintf('%7d',$ii); print ' '.(utf8::is_utf8($fn)?'1':'0'); print ' '.nhex($fn,$ii,4); print ' '.nhex($fn,$ii,12); print ' '.substr($fn,0,$ii)."\n"; my $hbadc=unpack("H*",substr($fn,$ii-1,1)); $bad{$hbadc}++; $bad4{nhex($fn,$ii,4)}++; last; } # ne } # ii; } # finddiff else { } } # listdiff } # hh ne hh2 else { # print $hh.' '.$hh2.' **OK** '.$f +n."\n" if ($listall); } $space{$hh}++; push @{$names{$hh}},$fn; } print "differences:$diff\n"; for my $kk (sort keys %bad) { print $kk.' '.$bad{$kk}."\n"; } for my $kk (sort keys %bad4) { print $kk.' '.$bad4{$kk}."\n"; } } else { # simple mode for my $fn (@$list) { my $hh=&{$sub0}($fn,$seed); if ($output) { print $oh $hh.' - '.$fn."\n"; } $space{$hh}++; push @{$names{$hh}},$fn; } } if ($output) { close $oh or die "cant close oh $output $!"; } # count collisions/hits my @col; for my $kk (sort keys %space) { $col[$space{$kk}]++;} # fill in missings; for my $n (@col){ $n=0 unless ($n);} $col[0]=4294967295-$hashct; my $ct=0; print "Hashed:$hashct\n"; print "hits n\n"; for my $n (@col){ print sprintf('%4d',$ct).' '.sprintf('%10u',$n)."\n" if ($n); $ct++; } if ($printif) { # print lines lists with more than this collisions for my $kk (sort keys %space) { my $doprint=0; if ($space{$kk} >= $printif) { print 'hash='.$kk.' hits='.sprintf('%4d',$space{$kk})."\n" +; for my $fn (@{$names{$kk}}){ print ' '.$fn."\n"; } } # printf } # kk } # printif exit; sub finder { # cheap but deadly my @txts; my $dir=shift; find(sub {push @txts,$File::Find::name; }, $dir); return \@txts; } ##################### # http://www.perlmonks.org/?node_id=315881 ##################### { # no use integer # http://www.perlmonks.org/?node_id=315881 # http://burtleburtle.net/bob/c/lookup2.c use constant GOLDEN_RATIO => 0x9e3779b9; use constant A => 0; use constant B => 1; use constant C => 2; sub mix ($$$) { $_[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); } sub mixexp ($$$) { $_[A] -= $_[B]; ja0(' a1-b' ,$_[A]); $_[A] -= $_[C]; ja0(' a1-c' ,$_[A]); bxor(' a1-x c>13 ',$_[A],$_[C],'>>',13); { no integer; $_[A] ^= ($_[C]>>13); } ja0(' a1-x c>13',$_[A]); $_[B] -= $_[C]; jb0(' b1-c' ,$_[B]); $_[B] -= $_[A]; jb0(' b1-a' ,$_[B]); bxor(' b1-x a<8 ',$_[B],$_[A],'<<', 8); { no integer; $_[B] ^= ($_[A]<< 8); } jb0(' b1-x a< 8',$_[B]); $_[C] -= $_[A]; jc0(' c1-a' ,$_[C]); use Devel::Peek; Dump($_[C]); $_[C] -= $_[B]; jc0(' c1-b' ,$_[C]); Dump($_[C]); bxor(' c1-x b>13 ',$_[C],$_[B],'>>',13); { no integer; $_[C] ^= ($_[B]>>13); } jc0(' c1-x b>13',$_[C]); $_[A] -= $_[B]; ja0(' a2-b' ,$_[A]); $_[A] -= $_[C]; ja0(' a2-c' ,$_[A]); bxor(' a2-x c>12 ',$_[A],$_[C],'>>',12); { no integer; $_[A] ^= ($_[C]>>12); } ja0(' a2-x c>12',$_[A]); $_[B] -= $_[C]; jb0(' b2-c' ,$_[B]); $_[B] -= $_[A]; jb0(' b2-a' ,$_[B]); bxor(' b2-x a<16 ',$_[B],$_[A],'<<',16); { no integer; $_[B] ^= ($_[A]<<16); } jb0(' b2-x a<16',$_[B]); $_[C] -= $_[A]; jc0(' c2-a' ,$_[C]); $_[C] -= $_[B]; jc0(' c2-b' ,$_[C]); bxor(' c2-x b>5 ',$_[C],$_[B],'>>',5); { no integer; $_[C] ^= ($_[B]>> 5); } jc0(' c2-x b>5 ',$_[C]); $_[A] -= $_[B]; ja0(' a3-b' ,$_[A]); $_[A] -= $_[C]; ja0(' a3-c' ,$_[A]); bxor(' a3-x c>3 ',$_[A],$_[C],'>>', 3); { no integer; $_[A] ^= ($_[C]>> 3); } ja0(' a3-x c>3 ',$_[A]); $_[B] -= $_[C]; jb0(' b3-c' ,$_[B]); $_[B] -= $_[A]; jb0(' b3-a' ,$_[B]); bxor(' b3-x a<10 ',$_[B],$_[A],'<<',10); { no integer; $_[B] ^= ($_[A]<<10); } jb0(' b3-x a<10',$_[B]); $_[C] -= $_[A]; jc0(' c3-a' ,$_[C]); $_[C] -= $_[B]; jc0(' c3-b' ,$_[C]); bxor(' c3-x b>15 ',$_[C],$_[B],'>>',15); { no integer; $_[C] ^= ($_[B]>>15); } jc0(' c3-x b>15 ',$_[C]); } sub mixui ($$$) { use integer; $_[A] -= $_[B]; $_[A] -= $_[C]; { no integer; $_[A] ^= ($_[C]>>13) +; } $_[B] -= $_[C]; $_[B] -= $_[A]; { no integer; $_[B] ^= ($_[A]<< 8) +; } $_[C] -= $_[A]; $_[C] -= $_[B]; { no integer; $_[C] ^= ($_[B]>>13) +; } $_[A] -= $_[B]; $_[A] -= $_[C]; { no integer; $_[A] ^= ($_[C]>>12) +; } $_[B] -= $_[C]; $_[B] -= $_[A]; { no integer; $_[B] ^= ($_[A]<<16) +; } $_[C] -= $_[A]; $_[C] -= $_[B]; { no integer; $_[C] ^= ($_[B]>> 5) +; } $_[A] -= $_[B]; $_[A] -= $_[C]; { no integer; $_[A] ^= ($_[C]>> 3) +; } $_[B] -= $_[C]; $_[B] -= $_[A]; { no integer; $_[B] ^= ($_[A]<<10) +; } $_[C] -= $_[A]; $_[C] -= $_[B]; { no integer; $_[C] ^= ($_[B]>>15) +; } } use constant KEY => 0; use constant INITHASH => 1; sub hash { # orig use integer; my ($a, $b, $c) = ( GOLDEN_RATIO, GOLDEN_RATIO, $_[INITHASH] ); my ($p, $len) = (0, length $_[KEY]); do { my($x,$y,$z) = unpack 'LLL', substr($_[KEY] . (chr(0)x11), $p, + 12); $z||='0'; $z<<=8; mix($a += $x, $b += $y, $c += $z); $p += 12; } while $p <= $len; my $hex = unpack("H*", pack("N", $c)); return $hex; } sub hash2 { # NNN instead of LLL, $z=0 not '0' use integer; my ($a, $b, $c) = ( GOLDEN_RATIO, GOLDEN_RATIO, $_[INITHASH] ); my ($p, $len) = (0, length $_[KEY]); do { my($x,$y,$z) = unpack 'NNN', substr($_[KEY] . (chr(0)x11), $p, + 12); $z||=0; $z<<=8; mix($a += $x, $b += $y, $c += $z); $p += 12; } while $p <= $len; my $hex = unpack("H*", pack("N", $c)); return $hex; } sub hash20 { # $z=0 not '0' use integer; my ($a, $b, $c) = ( GOLDEN_RATIO, GOLDEN_RATIO, $_[INITHASH] ); my ($p, $len) = (0, length $_[KEY]); do { my($x,$y,$z) = unpack 'LLL', substr($_[KEY] . (chr(0)x11), $p, + 12); $z||=0; $z<<=8; mix($a += $x, $b += $y, $c += $z); $p += 12; } while $p <= $len; my $hex = unpack("H*", pack("N", $c)); return $hex; } sub hash3 { # more faithfull to # http://burtleburtle.net/bob/c/lookup +2.c use integer; my ($a, $b, $c) = ( GOLDEN_RATIO, GOLDEN_RATIO, $_[INITHASH] ); my ($p, $length) = (0, length $_[KEY]); my $len=$length; my($x,$y,$z); while ($len>=12) { ($x,$y,$z) = unpack 'LLL', substr($_[KEY], $p, 12); $a+=$x;$b+=$y;$c+=$z; mix($a, $b, $c); $p += 12; $len-=12; } ($x,$y,$z) = unpack 'LLL', substr($_[KEY] . (chr(0)x12), $p, 1 +2); $z<<=8; # /* the first byte of c is reserved for the length * +/ $z+=$length; $a+=$x;$b+=$y;$c+=$z; mix($a, $b, $c); my $hex = unpack("H*", pack("N", $c)); return $hex; } sub hash3exp { # more faithfull to # http://burtleburtle.net/bob/c/loo +kup2.c use integer; my ($a, $b, $c) = ( GOLDEN_RATIO, GOLDEN_RATIO, $_[INITHASH] ); abc(' entry ',$a,$b,$c); my ($p, $length) = (0, length $_[KEY]); my $len=$length; my($x,$y,$z); while ($len>=12) { ($x,$y,$z) = unpack 'LLL', substr($_[KEY], $p, 12); xyz(' loop ',$x,$y,$z); $a+=$x;$b+=$y;$c+=$z; abc(' loop+ ',$a,$b,$c); mix($a, $b, $c); abc(' lout ',$a,$b,$c); $p += 12; $len-=12; } ($x,$y,$z) = unpack 'LLL', substr($_[KEY] . (chr(0)x12), $p, 1 +2); xyz(' post1 ',$x,$y,$z); $z<<=8; # /* the first byte of c is reserved for the length * +/ $z+=$length; xyz(' post8 ',$x,$y,$z); $a+=$x;$b+=$y;$c+=$z; abc(' post+ ',$a,$b,$c); mix($a, $b, $c); abc(' pout ',$a,$b,$c); my $hex = unpack("H*", pack("N", $c)); return $hex; } sub hash3ui { # more faithfull to # http://burtleburtle.net/bob/c/look +up2.c use integer; my ($a, $b, $c) = ( GOLDEN_RATIO, GOLDEN_RATIO, $_[INITHASH] ); my ($p, $length) = (0, length $_[KEY]); my $len=$length; my($x,$y,$z); while ($len>=12) { ($x,$y,$z) = unpack 'LLL', substr($_[KEY], $p, 12); $a+=$x;$b+=$y;$c+=$z; mixui($a, $b, $c); $p += 12; $len-=12; } ($x,$y,$z) = unpack 'LLL', substr($_[KEY] . (chr(0)x12), $p, 1 +2); $z<<=8; # /* the first byte of c is reserved for the length * +/ $z+=$length; $a+=$x;$b+=$y;$c+=$z; mixui($a, $b, $c); my $hex = unpack("H*", pack("N", $c)); return $hex; } } # no use integer ##################### # # has use integer ##################### { # has use integer/bytes use integer; use bytes; # http://www.perlmonks.org/?node_id=315881 # http://burtleburtle.net/bob/c/lookup2.c use constant GOLDEN_RATIO => 0x9e3779b9; use constant A => 0; use constant B => 1; use constant C => 2; use constant FFFFFFFF => 0xffffffff; sub mix4 ($$$) { # per http://www.perlmonks.org/?node_id=1203705 this is a revised 32bi +t under 'use integer'; $_[A] -= $_[B]; $_[A] -= $_[C]; { no integer; $_[A] ^= ($_[C]>>13) +; } $_[B] -= $_[C]; $_[B] -= $_[A]; { no integer; $_[B] ^= ($_[A]<< 8) +; } $_[C] -= $_[A]; $_[C] -= $_[B]; { no integer; $_[C] ^= ($_[B]>>13) +; } $_[A] -= $_[B]; $_[A] -= $_[C]; { no integer; $_[A] ^= ($_[C]>>12) +; } $_[B] -= $_[C]; $_[B] -= $_[A]; { no integer; $_[B] ^= ($_[A]<<16) +; } $_[C] -= $_[A]; $_[C] -= $_[B]; { no integer; $_[C] ^= ($_[B]>> 5) +; } $_[A] -= $_[B]; $_[A] -= $_[C]; { no integer; $_[A] ^= ($_[C]>> 3) +; } $_[B] -= $_[C]; $_[B] -= $_[A]; { no integer; $_[B] ^= ($_[A]<<10) +; } $_[C] -= $_[A]; $_[C] -= $_[B]; { no integer; $_[C] ^= ($_[B]>>15) +; } } sub mix4x ($$$) { # per http://www.perlmonks.org/?node_id=1203705 this is wrong $_[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); } sub mix4exp ($$$) { # per http://www.perlmonks.org/?node_id=1203705 this is a revised 32bi +t under 'use integer'; $_[A] -= $_[B]; ja0(' a1-b' ,$_[A]); $_[A] -= $_[C]; ja0(' a1-c' ,$_[A]); bxor(' a1-x c>13 ',$_[A],$_[C],'>>',13); { no integer; $_[A] ^= ($_[C]>>13); } ja0(' a1-x c>13',$_[A]); $_[B] -= $_[C]; jb0(' b1-c' ,$_[B]); $_[B] -= $_[A]; jb0(' b1-a' ,$_[B]); bxor(' b1-x a<8 ',$_[B],$_[A],'<<', 8); { no integer; $_[B] ^= ($_[A]<< 8); } jb0(' b1-x a< 8',$_[B]); $_[C] -= $_[A]; jc0(' c1-a' ,$_[C]); use Devel::Peek; Dump($_[C]); $_[C] -= $_[B]; jc0(' c1-b' ,$_[C]); Dump($_[C]); bxor(' c1-x b>13 ',$_[C],$_[B],'>>',13); { no integer; $_[C] ^= ($_[B]>>13); } jc0(' c1-x b>13',$_[C]); $_[A] -= $_[B]; ja0(' a2-b' ,$_[A]); $_[A] -= $_[C]; ja0(' a2-c' ,$_[A]); bxor(' a2-x c>12 ',$_[A],$_[C],'>>',12); { no integer; $_[A] ^= ($_[C]>>12); } ja0(' a2-x c>12',$_[A]); $_[B] -= $_[C]; jb0(' b2-c' ,$_[B]); $_[B] -= $_[A]; jb0(' b2-a' ,$_[B]); bxor(' b2-x a<16 ',$_[B],$_[A],'<<',16); { no integer; $_[B] ^= ($_[A]<<16); } jb0(' b2-x a<16',$_[B]); $_[C] -= $_[A]; jc0(' c2-a' ,$_[C]); $_[C] -= $_[B]; jc0(' c2-b' ,$_[C]); bxor(' c2-x b>5 ',$_[C],$_[B],'>>',5); { no integer; $_[C] ^= ($_[B]>> 5); } jc0(' c2-x b>5 ',$_[C]); $_[A] -= $_[B]; ja0(' a3-b' ,$_[A]); $_[A] -= $_[C]; ja0(' a3-c' ,$_[A]); bxor(' a3-x c>3 ',$_[A],$_[C],'>>', 3); { no integer; $_[A] ^= ($_[C]>> 3); } ja0(' a3-x c>3 ',$_[A]); $_[B] -= $_[C]; jb0(' b3-c' ,$_[B]); $_[B] -= $_[A]; jb0(' b3-a' ,$_[B]); bxor(' b3-x a<10 ',$_[B],$_[A],'<<',10); { no integer; $_[B] ^= ($_[A]<<10); } jb0(' b3-x a<10',$_[B]); $_[C] -= $_[A]; jc0(' c3-a' ,$_[C]); $_[C] -= $_[B]; jc0(' c3-b' ,$_[C]); bxor(' c3-x b>15 ',$_[C],$_[B],'>>',15); { no integer; $_[C] ^= ($_[B]>>15); } jc0(' c3-x b>15 ',$_[C]); } sub mix8ni ($$$) { # this shoud get the same hash on 32 and 64 bit ints # F'it, fix them all, all the time, cost is 4 extra & FFFFFFFF's $_[A] &= FFFFFFFF; $_[B] &= FFFFFFFF; $_[C] &= FFFFFFFF; $_[A] -= $_[B]; $_[A] -= $_[C]; { no integer; $_[A] = ( $_[A] ^ ($ +_[C]>>13) ) & FFFFFFFF; } $_[B] -= $_[C]; $_[B] -= $_[A]; { no integer; $_[B] = ( $_[B] ^ ($ +_[A]<< 8) ) & FFFFFFFF; } $_[C] -= $_[A]; $_[C] -= $_[B]; { no integer; $_[C] = ( $_[C] ^ ($ +_[B]>>13) ) & FFFFFFFF; } $_[A] -= $_[B]; $_[A] -= $_[C]; { no integer; $_[A] = ( $_[A] ^ ($ +_[C]>>12) ) & FFFFFFFF; } $_[B] -= $_[C]; $_[B] -= $_[A]; { no integer; $_[B] = ( $_[B] ^ ($ +_[A]<<16) ) & FFFFFFFF; } $_[C] -= $_[A]; $_[C] -= $_[B]; { no integer; $_[C] = ( $_[C] ^ ($ +_[B]>> 5) ) & FFFFFFFF; } $_[A] -= $_[B]; $_[A] -= $_[C]; { no integer; $_[A] = ( $_[A] ^ ($ +_[C]>> 3) ) & FFFFFFFF; } $_[B] -= $_[C]; $_[B] -= $_[A]; { no integer; $_[B] = ( $_[B] ^ ($ +_[A]<<10) ) & FFFFFFFF; } $_[C] -= $_[A]; $_[C] -= $_[B]; { no integer; $_[C] = ( $_[C] ^ ($ +_[B]>>15) ) & FFFFFFFF; } } sub mix8 ($$$) { # this shoud get the same hash on 32 and 64 bit ints # F'it, fix them all, all the time, cost is 4 extra & FFFFFFFF's $_[A] &= FFFFFFFF; $_[B] &= FFFFFFFF; $_[C] &= FFFFFFFF; $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ ($_[C]>>13) ) & + FFFFFFFF; $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( $_[B] ^ ($_[A]<< 8) ) & + FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( $_[C] ^ ($_[B]>>13) ) & + FFFFFFFF; $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ ($_[C]>>12) ) & + FFFFFFFF; $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( $_[B] ^ ($_[A]<<16) ) & + FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( $_[C] ^ ($_[B]>> 5) ) & + FFFFFFFF; $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ ($_[C]>> 3) ) & + FFFFFFFF; $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( $_[B] ^ ($_[A]<<10) ) & + FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( $_[C] ^ ($_[B]>>15) ) & + FFFFFFFF; } sub mix8exp ($$$) { # way extra debug # this shoud get the same hash on 32 and 64 bit ints abc(' m0 ',$_[A],$_[B],$_[C]); $_[A] &= FFFFFFFF; $_[B] &= FFFFFFFF; $_[C] &= FFFFFFFF; abc(' m &ff ',$_[A],$_[B],$_[C]); # $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ ($_[C] + >>13) ) & FFFFFFFF; $_[A] -= $_[B]; + ja0(' a1-b' ,$_[A]); $_[A] -= $_[C]; + ja0(' a1-c' ,$_[A]); bxor(' a1-x c>13 ',$_[A],$_[C],'>>',13); $_[A] = ( $_[A] ^ ($_[C] + >>13) ) & FFFFFFFF; ja0(' a1-x c>13',$_[A]); # $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( $_[B] ^ ($_[A] + << 8) ) & FFFFFFFF; $_[B] -= $_[C]; + jb0(' b1-c' ,$_[B]); $_[B] -= $_[A]; + jb0(' b1-a' ,$_[B]); bxor(' b1-x a< 8 ',$_[B],$_[A],'<<',8); $_[B] = ( $_[B] ^ ($_[A] + << 8) ) & FFFFFFFF; jb0(' b1-x a< 8',$_[B]); # $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( $_[C] ^ ($_[B] + >>13) ) & FFFFFFFF; $_[C] -= $_[A]; + jc0(' c1-a' ,$_[C]); $_[C] -= $_[B]; + jc0(' c1-b' ,$_[C]); bxor(' c1-x b>13 ',$_[C],$_[B],'>>',13); $_[C] = ( $_[C] ^ ($_[B] + >>13) ) & FFFFFFFF; jc0(' c1-x b>13',$_[C]); # $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ ($_[C] + >>12) ) & FFFFFFFF; $_[A] -= $_[B]; + ja0(' a2-b' ,$_[A]); $_[A] -= $_[C]; + ja0(' a2-c' ,$_[A]); bxor(' a2-x c>12 ',$_[A],$_[C],'>>',12); $_[A] = ( $_[A] ^ ($_[C] + >>12) ) & FFFFFFFF; ja0(' a2-x c>12',$_[A]); # $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( ($_[B] ^ ($_[A] + <<16)) ) & FFFFFFFF; $_[B] -= $_[C]; + jb0(' b2-c' ,$_[B]); $_[B] -= $_[A]; + jb0(' b2-a' ,$_[B]); bxor(' b2-x a<16 ',$_[B],$_[A],'<<',16); $_[B] = ( ($_[B] ^ ($_[A] + <<16)) ) & FFFFFFFF; jb0(' b2-x a<16',$_[B]); # $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( ($_[C] ^ ($_[B] + >> 5)) ) & FFFFFFFF; $_[C] -= $_[A]; + jc0(' c2-a' ,$_[C]); $_[C] -= $_[B]; + jc0(' c2-b' ,$_[C]); bxor(' c2-x b> 5 ',$_[C],$_[B],'>>',5); $_[C] = ( ($_[C] ^ ($_[B] + >> 5)) ) & FFFFFFFF; jc0(' c2-x b> 5',$_[C]); # $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( ($_[A] ^ ($_[C] + >> 3)) ) & FFFFFFFF; $_[A] -= $_[B]; + ja0(' a3-b' ,$_[A]); $_[A] -= $_[C]; + ja0(' a3-c' ,$_[A]); bxor(' a3-x c> 3 ',$_[A],$_[C],'>>',3); $_[A] = ( ($_[A] ^ ($_[C] + >> 3)) ) & FFFFFFFF; ja0(' a3-x c> 3',$_[A]); # $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( ($_[B] ^ ($_[A] + <<10)) ) & FFFFFFFF; $_[B] -= $_[C]; + jb0(' b3-c' ,$_[B]); $_[B] -= $_[A]; + jb0(' b3-a' ,$_[B]); bxor(' b3-x a<10 ',$_[B],$_[A],'<<',10); $_[B] = ( ($_[B] ^ ($_[A] + <<10)) ) & FFFFFFFF; jb0(' b3-x a<10',$_[B]); # $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( ($_[C] ^ ($_[B] + >>15)) ) & FFFFFFFF; $_[C] -= $_[A]; + jc0(' c3-a' ,$_[C]); $_[C] -= $_[B]; + jc0(' c3-b' ,$_[C]); bxor(' c3-x b>15 ',$_[C],$_[B],'>>',15); $_[C] = ( ($_[C] ^ ($_[B] + >>15)) ) & FFFFFFFF; jc0(' c3-x b>15',$_[C]); } sub mix8wide ($$$) { # same as mix8 above with extra spaces and parens to match below $_[A] &= FFFFFFFF; $_[B] &= FFFFFFFF; $_[C] &= FFFFFFFF; $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ ($_[C] + >>13) ) & FFFFFFFF; $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( $_[B] ^ ($_[A] + << 8) ) & FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( $_[C] ^ ($_[B] + >>13) ) & FFFFFFFF; $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ ($_[C] + >>12) ) & FFFFFFFF; $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( ($_[B] ^ ($_[A] + <<16)) ) & FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( ($_[C] ^ ($_[B] + >> 5)) ) & FFFFFFFF; $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( ($_[A] ^ ($_[C] + >> 3)) ) & FFFFFFFF; $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( ($_[B] ^ ($_[A] + <<10)) ) & FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( ($_[C] ^ ($_[B] + >>15)) ) & FFFFFFFF; } sub mix80f3 ($$$) { $_[C] &= FFFFFFFF; $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ ($_[C] + >>13) ); # a dont need fixen cuz its always << $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( $_[B] ^ ($_[A] + << 8) ) & FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( $_[C] ^ ($_[B] + >>13) ) & FFFFFFFF; $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ ($_[C] + >>12) ); $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( ($_[B] ^ ($_[A] + <<16)) ) & FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( ($_[C] ^ ($_[B] + >> 5)) ) & FFFFFFFF; $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( ($_[A] ^ ($_[C] + >> 3)) ) & FFFFFFFF; # fix lst one tho , just cuz $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( ($_[B] ^ ($_[A] + <<10)) ) & FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( ($_[C] ^ ($_[B] + >>15)) ) & FFFFFFFF; } sub mix80f2 ($$$) { # opps c could have overflowed and introduced a 1 rather than a 0 on > +> 13 $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ (($_[C] & FFFF +FFFF ) >>13) ); $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( $_[B] ^ ($_[A] + << 8) ) & FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( $_[C] ^ ($_[B] + >>13) ) & FFFFFFFF; $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ ($_[C] + >>12) ); $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( ($_[B] ^ ($_[A] + <<16)) ) & FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( ($_[C] ^ ($_[B] + >> 5)) ) & FFFFFFFF; $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( ($_[A] ^ ($_[C] + >> 3)) ) & FFFFFFFF; $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( ($_[B] ^ ($_[A] + <<10)) ) & FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( ($_[C] ^ ($_[B] + >>15)) ) & FFFFFFFF; } sub mix80f ($$$) { # opps c could have overflowed and introd doce a 1 rather than a 0 on +>> 13 $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ (($_[C] & FFFF +FFFF ) >>13) ); $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( $_[B] ^ ($_[A] + << 8) ); $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( $_[C] ^ (($_[B] & FFFF +FFFF ) >>13) ); $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ (($_[C] & FFFF +FFFF ) >>12) ); $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( ($_[B] ^ ($_[A] + <<16)) ) & FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( ($_[C] ^ ($_[B] + >> 5)) ) & FFFFFFFF; $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( ($_[A] ^ ($_[C] + >> 3)) ) & FFFFFFFF; $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( ($_[B] ^ ($_[A] + <<10)) ) & FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( ($_[C] ^ ($_[B] + >>15)) ) & FFFFFFFF; } sub mix8a ($$$) { # kinda failtfull to mix2 http://burtleburtle.net/bob/c/lookup2.c but +leading truncate; $_[A] &= FFFFFFFF; $_[B] &= FFFFFFFF; $_[C] &= FFFFFFFF; $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ ($_[C] + >>13) ); $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( $_[B] ^ ($_[A] + << 8) ); $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( $_[C] ^ (($_[B] & FFFF +FFFF ) >>13) ); $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ (($_[C] & FFFF +FFFF ) >>12) ); $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( ($_[B] ^ ($_[A] + <<16)) ) & FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( ($_[C] ^ ($_[B] + >> 5)) ) & FFFFFFFF; $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( ($_[A] ^ ($_[C] + >> 3)) ) & FFFFFFFF; $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( ($_[B] ^ ($_[A] + <<10)) ) & FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( ($_[C] ^ ($_[B] + >>15)) ) & FFFFFFFF; } sub mix80 ($$$) { # kinda failtfull to mix2 http://burtleburtle.net/bob/c/lookup2.c $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ ($_[C] + >>13) ); $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( $_[B] ^ ($_[A] + << 8) ); $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( $_[C] ^ (($_[B] & FFFF +FFFF ) >>13) ); $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( $_[A] ^ (($_[C] & FFFF +FFFF ) >>12) ); $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( ($_[B] ^ ($_[A] + <<16)) ) & FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( ($_[C] ^ ($_[B] + >> 5)) ) & FFFFFFFF; $_[A] -= $_[B]; $_[A] -= $_[C]; $_[A] = ( ($_[A] ^ ($_[C] + >> 3)) ) & FFFFFFFF; $_[B] -= $_[C]; $_[B] -= $_[A]; $_[B] = ( ($_[B] ^ ($_[A] + <<10)) ) & FFFFFFFF; $_[C] -= $_[A]; $_[C] -= $_[B]; $_[C] = ( ($_[C] ^ ($_[B] + >>15)) ) & FFFFFFFF; } # this is mix2 @ http://burtleburtle.net/bob/c/lookup2.c ##define mix2(a,b,c) \ #{ \ # a -= b; a -= c; a ^= (c>>13); \ # b -= c; b -= a; b ^= (a<< 8); \ # c -= a; c -= b; c ^= ((b&0xffffffff)>>13); \ # a -= b; a -= c; a ^= ((c&0xffffffff)>>12); \ # b -= c; b -= a; b = (b ^ (a<<16)) & 0xffffffff; \ # c -= a; c -= b; c = (c ^ (b>> 5)) & 0xffffffff; \ # a -= b; a -= c; a = (a ^ (c>> 3)) & 0xffffffff; \ # b -= c; b -= a; b = (b ^ (a<<10)) & 0xffffffff; \ # c -= a; c -= b; c = (c ^ (b>>15)) & 0xffffffff; \ #} use constant KEY => 0; use constant INITHASH => 1; sub hashi { # original BrowserUk inside use integer use integer; my ($a, $b, $c) = ( GOLDEN_RATIO, GOLDEN_RATIO, $_[INITHASH] ); my ($p, $len) = (0, length $_[KEY]); do { my($x,$y,$z) = unpack 'LLL', substr($_[KEY] . (chr(0)x11), $p, + 12); $z||='0'; $z<<=8; mix4x($a += $x, $b += $y, $c += $z); $p += 12; } while $p <= $len; my $hex = unpack("H*", pack("N", $c)); return $hex; } sub hash2i { # hash2 inside use integer use integer; my ($a, $b, $c) = ( GOLDEN_RATIO, GOLDEN_RATIO, $_[INITHASH] ); my ($p, $len) = (0, length $_[KEY]); do { my($x,$y,$z) = unpack 'NNN', substr($_[KEY] . (chr(0)x11), $p, + 12); $z||=0; $z<<=8; mix4x($a += $x, $b += $y, $c += $z); $p += 12; } while $p <= $len; my $hex = unpack("H*", pack("N", $c)); return $hex; } sub hash3s { # returns a "hash3" style sub reference using the "mixer" + sub ref named as arg easy to make hash table entries my $mix=shift; return sub { use integer; my ($a, $b, $c) = ( GOLDEN_RATIO, GOLDEN_RATIO, $_[INITHASH] ) +; my ($p, $length) = (0, length $_[KEY]); my $len=$length; my($x,$y,$z); while ($len>=12) { ($x,$y,$z) = unpack 'LLL', substr($_[KEY], $p, 12); $a+=$x;$b+=$y;$c+=$z; &{$mix}($a, $b, $c); $p += 12; $len-=12; } ($x,$y,$z) = unpack 'LLL', substr($_[KEY] . (chr(0)x12), $ +p, 12); $z<<=8; # /* the first byte of c is reserved for the leng +th */ $z+=$length; $a+=$x;$b+=$y;$c+=$z; &{$mix}($a, $b, $c); my $hex = unpack("H*", pack("N", $c)); return $hex; }; } # hash3s sub hash3sexp { # returns a "hash3" style sub reference using the "mix +er" sub ref named as arg easy to make hash table entries my $mix=shift; my $mixname=shift; return sub { print 'name:'.$mixname."\n"; use integer; my ($a, $b, $c) = ( GOLDEN_RATIO, GOLDEN_RATIO, $_[INITHASH] ) +; abc(' entry ',$a,$b,$c); my ($p, $length) = (0, length $_[KEY]); my $len=$length; my($x,$y,$z); while ($len>=12) { ($x,$y,$z) = unpack 'LLL', substr($_[KEY], $p, 12); xyz(' loop ',$x,$y,$z); $a+=$x;$b+=$y;$c+=$z; abc(' loop+ ',$a,$b,$c); &{$mix}($a, $b, $c); abc(' lout ',$a,$b,$c); $p += 12; $len-=12; } ($x,$y,$z) = unpack 'LLL', substr($_[KEY] . (chr(0)x12), $ +p, 12); xyz(' post1 ',$x,$y,$z); $z<<=8; # /* the first byte of c is reserved for the leng +th */ $z+=$length; xyz(' post8 ',$x,$y,$z); $a+=$x;$b+=$y;$c+=$z; abc(' post+ ',$a,$b,$c); &{$mix}($a, $b, $c); abc(' pout ',$a,$b,$c); my $hex = unpack("H*", pack("N", $c)); return $hex; }; } # hash3sexp sub hash38 { # final good pick, mix8 is faithful, and this algo is more faithful, m +akes it easy to follow use integer; my ($a, $b, $c) = ( GOLDEN_RATIO, GOLDEN_RATIO, $_[INITHASH] ); my ($p, $length) = (0, length $_[KEY]); my $len=$length; my($x,$y,$z); while ($len>=12) { ($x,$y,$z) = unpack 'LLL', substr($_[KEY], $p, 12); $a+=$x;$b+=$y;$c+=$z; mix8($a, $b, $c); $p += 12; $len-=12; } ($x,$y,$z) = unpack 'LLL', substr($_[KEY] . (chr(0)x12), $p, 1 +2); $z<<=8; # /* the first byte of c is reserved for the length * +/ $z+=$length; $a+=$x;$b+=$y;$c+=$z; mix8($a, $b, $c); my $hex = unpack("H*", pack("N", $c)); return $hex; } # hash38 sub hash38exp { # this is the over debuged version use integer; my ($a, $b, $c) = ( GOLDEN_RATIO, GOLDEN_RATIO, $_[INITHASH] ); abc(' entry ',$a,$b,$c); my ($p, $length) = (0, length $_[KEY]); my $len=$length; my($x,$y,$z); while ($len>=12) { ($x,$y,$z) = unpack 'LLL', substr($_[KEY], $p, 12); xyz(' loop ',$x,$y,$z); $a+=$x;$b+=$y;$c+=$z; abc(' loop+ ',$a,$b,$c); mix8exp($a, $b, $c); abc(' lout ',$a,$b,$c); $p += 12; $len-=12; } ($x,$y,$z) = unpack 'LLL', substr($_[KEY] . (chr(0)x12), $p, 1 +2); xyz(' post1 ',$x,$y,$z); $z<<=8; # /* the first byte of c is reserved for the length * +/ $z+=$length; xyz(' post8 ',$x,$y,$z); $a+=$x;$b+=$y;$c+=$z; abc(' post+ ',$a,$b,$c); mix8exp($a, $b, $c); abc(' pout ',$a,$b,$c); my $hex = unpack("H*", pack("N", $c)); return $hex; } # hash38 } # has use integer/bytes sub hashfish{ #http://search.cpan.org/~shlomif/Digest-JHash/lib/Digest/JHash.pm # http://www.perlmonks.org/?node_id=315984 # use Digest::JHash; my $hex = unpack("H*", pack("N",Digest::JHash::jhash($_[0]))); + return $hex; } # fishhash sub hashfishic { return unpack("H*", pack("N",jhashic($_[0]))); } sub hashfishs { return unpack("H*", pack("N",jhashs ($_[0]))); } sub hashfishu { return unpack("H*", pack("N",jhashu ($_[0]))); } sub abc{ my $when=shift; abc0(sprintf('%-15s',$when).' : '.'ABC ',@_); } sub abc0{ my $when=shift; my $a=shift; my $b=shift; my $c=shift; print sprintf('%-20s',$when).': '.sprintf('%16d',$a).' '.h64($a).' - + '.sprintf('%16d',$b).' '.h64($b).' - '.sprintf('%16d',$c).' '.h64($c +)."\n"; } sub xyz{ my $when=shift; abc0(sprintf('%-15s',$when).' : '.'XYZ ',@_); } sub order64 { my $name=shift; my $num=shift; # print $name.': Q :'.unpack("H*", pack("Q", $num))."\n"; # print $name.': N-hi :'.unpack("H*", pack("N", $num>>32))."\n"; # print $name.': N-low: '.unpack("H*", pack("N", $num))."\n"; print $name.' : '.h64($num)."\n"; } sub h64 { my $num=shift; return unpack("H*", pack("N", $num>>32)).' '.unpack("H*", pack("N", +$num)); } sub tobit32{ my $aa=shift; return ' '.unpack("B*", pack("N", $a +a)).' '.h64($aa); } sub h32 { my $num=shift; return ' '.unpack("H*", pack("N", $num)); } sub ja0{ my $when=shift; my $n=shift; j00($when,' : A ',0,$n); } sub jc0{ my $when=shift; my $n=shift; j00($when,' : C',2,$n); } sub jb0{ my $when=shift; my $n=shift; j00($when,' : B ',1,$n); } sub j00{ my $when=shift; my $var=shift; my $off=shift; my $n=shift; my $pad=''; if ($off>0) {$pad.=' - ';} if ($off>1) {$pad.=' - ';} print sprintf('%-15s',$when).$var.' : '.$pad.sprintf('%16d',$n).' '. +h64($n)."\n"; } sub nhex{ my $fn=shift; my $ii=shift; my $n=shift; my $pos=int(($ii-1)/$n)*$n; my $len=$ii-$pos; my $chr=substr($fn,$pos,$len); $chr=substr($chr.chr(0)x$n,0,$n); return unpack("H*", $chr); } # nhex sub bxor { my $desc=shift; my $aa=shift; my $c0=shift; my $dir=shift; my $move=shift; print $desc.': orig 1 :'.tobit($aa)."\n"; $desc=~s/./ /g; print $desc.': orig 2 :'.tobit($c0)."\n"; my $moved; my $md=sprintf('%-8s',$dir.$move); if ($dir eq '<<') {$moved=$c0<<$move;} else {$moved=$c0>>$move;} print $desc.': '.$md.':'.tobit($moved)."\n"; my $res=$aa^$moved; print $desc.': res :'.tobit($res)."\n"; } sub bxori { use integer; my $desc=shift; my $aa=shift; my $c0=shift; my $dir=shift; my $move=shift; print $desc.':iorig 1 :'.tobit($aa)."\n"; $desc=~s/./ /g; print $desc.':iorig 2 :'.tobit($c0)."\n"; my $moved; my $md=sprintf('%-8s',$dir.$move); if ($dir eq '<<') {$moved=$c0<<$move;} else {$moved=$c0>>$move;} print $desc.':i'.$md.':'.tobit($moved)."\n"; my $res=$aa^$moved; print $desc.':ires :'.tobit($res)."\n"; } sub tobit{ my $aa=shift; return unpack("B*", pack("N", $aa>>32)).' '.unpack("B*", pack("N", $ +aa)).' '.h64($aa); } __END__ perl hashtest1.pl -file bigtest -dir d:/ perl hashtest1.pl -file bigtest -seed 0 -hash orig Hashed:110405 hits n 0 4294856890 1 91335 2 3018 3 1028 4 386 5 184 6 218 7 52 8 70 9 169 10 141 11 5 12 12 13 8 14 7 15 2 16 1 18 5 19 2 20 9 28 3 29 1 30 15 31 26 88 1 111 1 perl hashtest1.pl -file bigtest -seed 0 -hash hash2 perl hashtest1.pl -file bigtest -seed 0 -hash orig -h2 hash20 perl hashtest1.pl -file bigtest -seed 1 -hash orig perl hashtest1.pl -file bigtest -seed 0 -hash hash3 perl hashtest1.pl -file bigtest -seed 0 -hash hashi perl hashtest1.pl -file bigtest -seed 0 -hash hash2i perl hashtest1.pl -file bigtest -seed 0 -hash hash3i perl hashtest1.pl -file bigtest -seed 0 -hash orig -h2 origi perl hashtest1.pl -file bigtest -seed 0 -hash hash2 -h2 hash2i perl hashtest1.pl -file bigtest -seed 0 -hash hash3 -h2 hash3i perl hashtest1.pl -file bigtest -seed 0 -hash hash30 perl hashtest1.pl -file bigtest -seed 0 -hash hash3a perl hashtest1.pl -file bigtest -seed 0 -hash hash3f perl hashtest1.pl -file bigtest -seed 0 -hash hash3f2 perl hashtest1.pl -file bigtest -seed 0 -hash hash3f3 perl hashtest1.pl -file bigtest -seed 0 -hash hash38 perl hashtest1.pl -file bigtest -seed 0 -hash hash3a -h2 hash38 perl hashtest1.pl -file bigtest -seed 0 -hash hash3f -h2 hash38 perl hashtest1.pl -file bigtest -seed 0 -hash hash3f2 -h2 hash38 perl hashtest1.pl -file bigtest -seed 0 -hash hash3f3 -h2 hash38 perl hashtest1.pl -file bigtest -seed 0 -hash fish perl hashtest1.pl -file bigtest -seed 0 -hash fish -h2 fix perl hashtest1.pl -file bigtest -seed 0 -hash fish -h2 fix -listdif +f -finddiff perl hashtest1.pl -file d3t.txt -seed 0 -hash fish -h2 fix -listdif +f -finddiff perl hashtest1.pl -file d3t.txt -seed 0 -hash fish -h2 fix -listdif +f -finddiff -blowup perl hashtest1.pl -file d3t.txt -seed 0 -hash fishodvs -h2 fixexp - +listdiff -finddiff -blowup perl hashtest1.pl -file d3t.txt -seed 0 -hash fishodvu -h2 fixexp - +listdiff -finddiff -blowup perl hashtest1.pl -file d3t.txt -seed 0 -hash fishic -h2 fix perl hashtest1.pl -file d3t.txt -seed 0 -hash fishic -h2 fix differences:0 Hashed:564263 hits n 0 4294403032 1 564181 2 41 perl hashtest1.pl -file d3t.txt -seed 0 -hash orig Hashed:564263 hits n 0 4294403032 1 496470 2 9270 3 2065 4 1416 5 891 6 566 7 329 8 294 9 540 10 450 11 101 12 152 13 53 14 83 15 60 16 61 17 40 18 40 19 28 20 15 21 24 22 7 23 11 24 8 25 5 26 5 27 3 28 15 29 7 30 40 31 74 32 2 37 1 38 2 39 1 40 2 48 2 49 2 50 1 51 1 52 1 57 1 61 1 64 1 74 1 77 1 102 1 perl hashtest1.pl -file d3t.txt -seed 0 -hash fix Hashed:564263 hits n 0 4294403032 1 564181 2 41 on 32bit perl \\pdhuck\d\active\misc\util\hashtest1.pl -file \\pdhuck\ +d\active\misc\util\smalltest.txt -hash hash34 -o c:\active\hashtest\s +mallout32.txt -noc perl hashtest1.pl -file smalltest.txt -seed 0 -hash hash38 -h2 hash3 +4 -o smallout64.txt hashcomp1.pl -file1 smallout64.txt -file2 \\bt\c\active\hashtest\small +out32.txt on32bit perl \\pdhuck\d\active\misc\util\hashtest1.pl -file \\pdhuck\d +\active\misc\util\smalltest.txt -noc -hash hash3exp -h2 hash34exp +-blowup

This is jhashodvs.c

#include "EXTERN.h" #include "perl.h" #include "XSUB.h" /* http://cpansearch.perl.org/src/SHLOMIF/Digest-JHash-0.10/JHash.xs * +/ /* overly debuged version of original with new fn name so they can coe +sixt */ /* Jenkins Hash http://burtleburtle.net/bob/hash/doobs.html */ typedef unsigned long int U32tf; /* unsigned 4-byte quantities */ void c_out0 ( char* str, U32tf a, U32tf b, U32tf c ) { printf( "%-20s%16u %016x - %16u %016x - %16u %016x \n", str,a,a,b,b +,c,c ); } const int DEBUGODV = 1; /* Need to constrain U32 to only 32 bits on 64 bit systems * For efficiency we only use the & 0xffffffff if required */ #if BYTEORDER > 0x4321 || defined(TRUNCATE_U32) #define MIXODV(a,b,c) \ { \ c_out0(" cm064 : ABC : ",a,b,c); \ a &= 0xffffffff; b &= 0xffffffff; c &= 0xffffffff; \ c_out0(" cm &ff : ABC : ",a,b,c); \ a -= b;\ c_out0(" cm a1-b : ABC : ",a,b,c); \ a -= c; \ c_out0(" cm a1-c : ABC : ",a,b,c); \ a ^= (c>>13);\ c_out0(" cm c1-x c>13 : ABC : ",a,b,c); \ a &= 0xffffffff; \ c_out0(" cm a1 : ABC : ",a,b,c); \ \ \ b -= c; b -= a; b ^= (a<<8); b &= 0xffffffff; \ c_out0(" cm b1 : ABC : ",a,b,c); \ \ c -= a; \ c_out0(" cm c1-a : ABC : ",a,b,c); \ c -= b; \ c_out0(" cm c1-b : ABC : ",a,b,c); \ c ^= (b>>13);\ c_out0(" cm c1-x b>13 : ABC : ",a,b,c); \ c &= 0xffffffff; \ c_out0(" cm c1 : ABC : ",a,b,c); \ \ \ \ a -= b; a -= c; a ^= (c>>12); a &= 0xffffffff; \ c_out0(" cm a2 : ABC : ",a,b,c); \ b -= c; b -= a; b ^= (a<<16); b &= 0xffffffff; \ c_out0(" cm b2 : ABC : ",a,b,c); \ c -= a; c -= b; c ^= (b>>5); c &= 0xffffffff; \ c_out0(" cm c2 : ABC : ",a,b,c); \ a -= b; a -= c; a ^= (c>>3); a &= 0xffffffff; \ c_out0(" cm a3 : ABC : ",a,b,c); \ b -= c; b -= a; b ^= (a<<10); b &= 0xffffffff; \ c_out0(" cm b3 : ABC : ",a,b,c); \ c -= a; c -= b; c ^= (b>>15); c &= 0xffffffff; \ c_out0(" cm c3 : ABC : ",a,b,c); \ } #else #define MIXODV(a,b,c) \ { \ c_out0(" cm032 : ABC : ",a,b,c); \ 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); \ } #endif U32 jhashs( SV* str ) { STRLEN rawlen; char* p; U32tf a, b, c, len, length; U32tf x, y, z; /* extract the string data and string length from the perl scalar +*/ p = (char*)SvPV(str, rawlen); length = len = (U32tf)rawlen; /* Test for undef or null string case and return 0 */ if ( length == 0 ) { DEBUGODV && printf( "Recieved a null or undef string!\n" ); return 0; } DEBUGODV && printf( "Received string %6i '%.*s'.\n", (int)len,(int +)len, p ); a = b = 0x9e3779b9; /* golden ratio suggested by Jenkins */ c = 0; c_out0(" centry : ABC : ",a,b,c); while (len >= 12) { a += (p[0] + (((U32tf)p[1])<<8) + (((U32tf)p[2])<<16) + (((U32tf)p[3])<<24)); b += (p[4] + (((U32tf)p[5])<<8) + (((U32tf)p[6])<<16) + (((U32tf)p[7])<<24)); c += (p[8] + (((U32tf)p[9])<<8) + (((U32tf)p[10])<<16) + (((U32tf)p[11])<<24)); c_out0(" cloop+ : ABC : ",a,b,c); MIXODV(a, b, c); c_out0(" clout : ABC : ",a,b,c); p += 12; len -= 12; } x = y = z= 0; z += length; switch(len) { case 11: z+=((U32tf)p[10]<<24); case 10: z+=((U32tf)p[9]<<16); case 9: z+=((U32tf)p[8]<<8); case 8: y+=((U32tf)p[7]<<24); case 7: y+=((U32tf)p[6]<<16); case 6: y+=((U32tf)p[5]<<8); case 5: y+=((U32tf)p[4]); case 4: x+=((U32tf)p[3]<<24); case 3: x+=((U32tf)p[2]<<16); case 2: x+=((U32tf)p[1]<<8); case 1: x+=((U32tf)p[0]); } c_out0(" cpost8 : XYZ : ",x,y,z); a+=x; b+=y;c+=z; c_out0(" cpost+ : ABC : ",a,b,c); MIXODV(a, b, c); c_out0(" cpout : ABC : ",a,b,c); DEBUGODV && printf( "Hash value is %d.\n", (int)(c) ); return(c); }

This is jhashodvu.c

#include "EXTERN.h" #include "perl.h" #include "XSUB.h" /* http://cpansearch.perl.org/src/SHLOMIF/Digest-JHash-0.10/JHash.xs * +/ /* overly documented version of fix, unsigned char* p ; */ /* Jenkins Hash http://burtleburtle.net/bob/hash/doobs.html */ typedef unsigned long int U32tf; /* unsigned 4-byte quantities */ void c_out0 ( char* str, U32tf a, U32tf b, U32tf c ) { printf( "%-20s%16u %016x - %16u %016x - %16u %016x \n", str,a,a,b,b +,c,c ); } const int DEBUGODV = 1; /* Need to constrain U32 to only 32 bits on 64 bit systems * For efficiency we only use the & 0xffffffff if required */ #if BYTEORDER > 0x4321 || defined(TRUNCATE_U32) #define MIXODV(a,b,c) \ { \ c_out0(" cm064 : ABC : ",a,b,c); \ a &= 0xffffffff; b &= 0xffffffff; c &= 0xffffffff; \ c_out0(" cm &ff : ABC : ",a,b,c); \ a -= b;\ c_out0(" cm a1-b : ABC : ",a,b,c); \ a -= c; \ c_out0(" cm a1-c : ABC : ",a,b,c); \ a ^= (c>>13);\ c_out0(" cm c1-x c>13 : ABC : ",a,b,c); \ a &= 0xffffffff; \ c_out0(" cm a1 : ABC : ",a,b,c); \ \ \ b -= c; b -= a; b ^= (a<<8); b &= 0xffffffff; \ c_out0(" cm b1 : ABC : ",a,b,c); \ \ c -= a; \ c_out0(" cm c1-a : ABC : ",a,b,c); \ c -= b; \ c_out0(" cm c1-b : ABC : ",a,b,c); \ c ^= (b>>13);\ c_out0(" cm c1-x b>13 : ABC : ",a,b,c); \ c &= 0xffffffff; \ c_out0(" cm c1 : ABC : ",a,b,c); \ \ \ \ a -= b; a -= c; a ^= (c>>12); a &= 0xffffffff; \ c_out0(" cm a2 : ABC : ",a,b,c); \ b -= c; b -= a; b ^= (a<<16); b &= 0xffffffff; \ c_out0(" cm b2 : ABC : ",a,b,c); \ c -= a; c -= b; c ^= (b>>5); c &= 0xffffffff; \ c_out0(" cm c2 : ABC : ",a,b,c); \ a -= b; a -= c; a ^= (c>>3); a &= 0xffffffff; \ c_out0(" cm a3 : ABC : ",a,b,c); \ b -= c; b -= a; b ^= (a<<10); b &= 0xffffffff; \ c_out0(" cm b3 : ABC : ",a,b,c); \ c -= a; c -= b; c ^= (b>>15); c &= 0xffffffff; \ c_out0(" cm c3 : ABC : ",a,b,c); \ } #else #define MIXODV(a,b,c) \ { \ c_out0(" cm032 : ABC : ",a,b,c); \ 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); \ } #endif U32 jhashu( SV* str ) { STRLEN rawlen; unsigned char* p; U32tf a, b, c, len, length; U32tf x, y, z; /* extract the string data and string length from the perl scalar +*/ p = (char*)SvPV(str, rawlen); length = len = (U32tf)rawlen; /* Test for undef or null string case and return 0 */ if ( length == 0 ) { DEBUGODV && printf( "Recieved a null or undef string!\n" ); return 0; } DEBUGODV && printf( "Received string %6i '%.*s'.\n", (int)len,(int +)len, p ); a = b = 0x9e3779b9; /* golden ratio suggested by Jenkins */ c = 0; c_out0(" centry : ABC : ",a,b,c); while (len >= 12) { a += (p[0] + (((U32tf)p[1])<<8) + (((U32tf)p[2])<<16) + (((U32tf)p[3])<<24)); b += (p[4] + (((U32tf)p[5])<<8) + (((U32tf)p[6])<<16) + (((U32tf)p[7])<<24)); c += (p[8] + (((U32tf)p[9])<<8) + (((U32tf)p[10])<<16) + (((U32tf)p[11])<<24)); c_out0(" cloop+ : ABC : ",a,b,c); MIXODV(a, b, c); c_out0(" clout : ABC : ",a,b,c); p += 12; len -= 12; } x = y = z= 0; z += length; switch(len) { case 11: z+=((U32tf)p[10]<<24); case 10: z+=((U32tf)p[9]<<16); case 9: z+=((U32tf)p[8]<<8); case 8: y+=((U32tf)p[7]<<24); case 7: y+=((U32tf)p[6]<<16); case 6: y+=((U32tf)p[5]<<8); case 5: y+=((U32tf)p[4]); case 4: x+=((U32tf)p[3]<<24); case 3: x+=((U32tf)p[2]<<16); case 2: x+=((U32tf)p[1]<<8); case 1: x+=((U32tf)p[0]); } c_out0(" cpost8 : XYZ : ",x,y,z); a+=x; b+=y;c+=z; c_out0(" cpost+ : ABC : ",a,b,c); MIXODV(a, b, c); c_out0(" cpout : ABC : ",a,b,c); DEBUGODV && printf( "Hash value is %d.\n", (int)(c) ); return(c); }

This is jhashic.c <code> /* from http://cpansearch.perl.org/src/SHLOMIF/Digest-JHash-0.10/JHash.xs */ /* changed char* p; to unsigned char* p; , new fn name so the can coexist */ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" /* Jenkins Hash http://burtleburtle.net/bob/hash/doobs.html */ const int DEBUG = 0; /* Need to constrain U32 to only 32 bits on 64 bit systems * For efficiency we only use the & 0xffffffff if required */ #if BYTEORDER > 0x4321 || defined(TRUNCATE_U32) #define MIX(a,b,c) \ { \ a &= 0xffffffff; b &= 0xffffffff; c &= 0xffffffff; \ a -= b; a -= c; a ^= (c>>13); a &= 0xffffffff; \ b -= c; b -= a; b ^= (a<<8); b &= 0xffffffff; \ c -= a; c -= b; c ^= (b>>13); c &= 0xffffffff; \ a -= b; a -= c; a ^= (c>>12); a &= 0xffffffff; \ b -= c; b -= a; b ^= (a<<16); b &= 0xffffffff; \ c -= a; c -= b; c ^= (b>>5); c &= 0xffffffff; \ a -= b; a -= c; a ^= (c>>3); a &= 0xffffffff; \ b -= c; b -= a; b ^= (a<<10); b &= 0xffffffff; \ c -= a; c -= b; c ^= (b>>15); c &= 0xffffffff; \ } #else #define MIX(a,b,c) \ { \ 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); \ } #endif U32 jhashic( SV* str ) { STRLEN rawlen; unsigned char* p; U32 a, b, c, len, length; /* extract the string data and string length from the perl scalar */ p = (char*)SvPV(str, rawlen); length = len = (U32)rawlen; /* Test for undef or null string case and r