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;
  
  
  

Reply via email to