stas 2003/11/04 10:22:53
Modified: t/response/TestPerl hash_attack.pm Log: Tels came up with an even faster hash function working U32. Submitted by: Tels <[EMAIL PROTECTED]> Revision Changes Path 1.3 +22 -0 modperl-2.0/t/response/TestPerl/hash_attack.pm Index: hash_attack.pm =================================================================== RCS file: /home/cvs/modperl-2.0/t/response/TestPerl/hash_attack.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- hash_attack.pm 3 Nov 2003 23:38:33 -0000 1.2 +++ hash_attack.pm 4 Nov 2003 18:22:53 -0000 1.3 @@ -114,6 +114,28 @@ # integer'). So we outsmart Perl and take modules 2*32 after each # calculation, emulating overflows that happen in C. sub hash { + my ($s) = @_; + my ($u, @c); + @c = split //, $s; + $u = 0; + for (@c) { + # (A % M) + (B % M) == (A + B) % M + # This works because '+' produces a NV, which is big enough to hold + # the intermidiate result. We only need the % before any "^" and "&" + # to get the result in the range for an I32. + # and << doesn't work on NV, so using 1 << 10 + $u += ord; + $u += $u * (1 << 10); $u %= MASK_U32; + $u ^= $u >> 6; + } + $u += $u << 3; $u %= MASK_U32; + $u ^= $u >> 11; $u %= MASK_U32; + $u += $u << 15; $u %= MASK_U32; + $u; +} + +# a bit slower but simpler version +sub hash_original { my $s = shift; my @c = split //, $s; my $u = 0;