]> Cypherpunks repositories - gostls13.git/commitdiff
Make adler32 cleaner.
authorTom Szymanski <tgs@google.com>
Wed, 18 Mar 2009 21:57:55 +0000 (14:57 -0700)
committerTom Szymanski <tgs@google.com>
Wed, 18 Mar 2009 21:57:55 +0000 (14:57 -0700)
R=rsc
APPROVED=rsc
DELTA=22  (9 added, 6 deleted, 7 changed)
OCL=26498
CL=26500

src/lib/hash/adler32.go
src/lib/hash/adler32_test.go

index e8876eba3350bd77dadfcf53c81c54fd9e7d221b..2964153831ef6e18f36b87fd1833024f69446c3d 100644 (file)
@@ -13,44 +13,46 @@ package adler32
 
 import "os"
 
+const (
+       mod = 65521;
+)
+
 // Digest represents the partial evaluation of a checksum.
 type Digest struct {
+       // invariant: (a < mod && b < mod) || a <= b
+       // invariant: a + b + 255 <= 0xffffffff
        a, b uint32;
-       n int;
 }
 
-const (
-       mod = 65521;
-       maxIter = 5552;  // max mod-free iterations before would overflow uint32
-)
-
 // NewDigest creates a new Digest.
 func NewDigest() *Digest {
-       return &Digest{1, 0, 0};
+       return &Digest{1, 0};
 }
 
 // Write updates the Digest with the incremental checksum generated by p.
 // It returns the number of bytes written; err is always nil.
 func (d *Digest) Write(p []byte) (nn int, err *os.Error) {
-       a, b, n := d.a, d.b, d.n;
+       a, b := d.a, d.b;
        for i := 0; i < len(p); i++ {
                a += uint32(p[i]);
                b += a;
-               n++;
-               if n == maxIter {
+               // invariant: a <= b
+               if b > (0xffffffff - 255) / 2 {
                        a %= mod;
                        b %= mod;
-                       n = 0;
+                       // invariant: a < mod && b < mod
+               } else {
+                       // invariant: a + b + 255 <= 2 * b + 255 <= 0xffffffff
                }
        }
-       d.a, d.b, d.n = a, b, n;
+       d.a, d.b = a, b;
        return len(p), nil
 }
 
 // Sum32 returns the 32-bit Adler-32 checksum of the data written to the Digest.
 func (d *Digest) Sum32() uint32 {
        a, b := d.a, d.b;
-       if a >= mod || b >= mod {
+       if b >= mod {
                a %= mod;
                b %= mod;
        }
index 97b918f13161d774e8353b5c893a46fa91e5ac37..6647ab18599a3990f97222e72667be1b2e80abeb 100644 (file)
@@ -47,6 +47,7 @@ var golden = []_Adler32Test {
        _Adler32Test{ 0x39111dd0, "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley" },
        _Adler32Test{ 0x91dd304f, "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule" },
        _Adler32Test{ 0x2e5d1316, "How can you write a big system without C++?  -Paul Glick" },
+       _Adler32Test{ 0xd0201df6, "'Invariant assertions' is the most elegant programming technique!  -Tom Szymanski" },
 }
 
 func TestGolden(t *testing.T) {