Change the token prehash function for better convergence
authorH. Peter Anvin <hpa@zytor.com>
Tue, 18 Sep 2007 19:38:07 +0000 (12:38 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Tue, 18 Sep 2007 19:38:07 +0000 (12:38 -0700)
Combining arithmetric (add) and bitwise (xor) mixing seems to give
better result than either.

With the new prehash function, we find a valid hash much quicker.

perllib/phash.ph
pptok.pl
tokhash.pl

index 6033427..3bb3a05 100644 (file)
@@ -42,8 +42,8 @@ sub prehash($$$) {
 
     foreach $c (unpack("C*", $key)) {
        $ko1 = $k1;  $ko2 = $k2;
-       $k1 = int32(rot($ko1,$s0)-rot($ko2, $s1)+$c);
-       $k2 = int32(rot($ko2,$s2)-rot($ko1, $s3)+$c);
+       $k1 = int32(rot($ko1,$s0)^int32(rot($ko2, $s1)+$c));
+       $k2 = int32(rot($ko2,$s2)^int32(rot($ko1, $s3)+$c));
     }
 
     # Create a bipartite graph...
index a0425b7..a835bf3 100755 (executable)
--- a/pptok.pl
+++ b/pptok.pl
@@ -191,8 +191,8 @@ if ($what eq 'c') {
     print OUT  "    while ((c = *p++) != 0) {\n";
     print OUT  "        uint32_t kn1, kn2;\n";
     print OUT  "        c |= 0x20; /* convert to lower case */\n";
-    printf OUT "        kn1 = rot(k1,%2d) - rot(k2,%2d) + c;\n", ${$sv}[0], ${$sv}[1];
-    printf OUT "        kn2 = rot(k2,%2d) - rot(k1,%2d) + c;\n", ${$sv}[2], ${$sv}[3];
+    printf OUT "        kn1 = rot(k1,%2d)^(rot(k2,%2d) + c);\n", ${$sv}[0], ${$sv}[1];
+    printf OUT "        kn2 = rot(k2,%2d)^(rot(k1,%2d) + c);\n", ${$sv}[2], ${$sv}[3];
     print OUT  "        k1 = kn1; k2 = kn2;\n";
     print OUT  "    }\n";
     print OUT  "\n";
index 5f1a9f4..9d5888b 100755 (executable)
@@ -187,8 +187,8 @@ print  "    const char *p = token;\n";
 print  "\n";
 
 print  "    while ((c = *p++) != 0) {\n";
-printf "        uint32_t kn1 = rot(k1,%2d) - rot(k2,%2d) + c;\n", ${$sv}[0], ${$sv}[1];
-printf "        uint32_t kn2 = rot(k2,%2d) - rot(k1,%2d) + c;\n", ${$sv}[2], ${$sv}[3];
+printf "        uint32_t kn1 = rot(k1,%2d)^(rot(k2,%2d) + c);\n", ${$sv}[0], ${$sv}[1];
+printf "        uint32_t kn2 = rot(k2,%2d)^(rot(k1,%2d) + c);\n", ${$sv}[2], ${$sv}[3];
 print  "        k1 = kn1; k2 = kn2;\n";
 print  "    }\n";
 print  "\n";