From 658ca49898b024753603f8f0a9194312469d466e Mon Sep 17 00:00:00 2001 From: Tom Szymanski Date: Wed, 18 Mar 2009 14:57:55 -0700 Subject: [PATCH] Make adler32 cleaner. R=rsc APPROVED=rsc DELTA=22 (9 added, 6 deleted, 7 changed) OCL=26498 CL=26500 --- src/lib/hash/adler32.go | 30 ++++++++++++++++-------------- src/lib/hash/adler32_test.go | 1 + 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/lib/hash/adler32.go b/src/lib/hash/adler32.go index e8876eba335..2964153831e 100644 --- a/src/lib/hash/adler32.go +++ b/src/lib/hash/adler32.go @@ -13,44 +13,46 @@ package adler32 import "os" -// Digest represents the partial evaluation of a checksum. -type Digest struct { - a, b uint32; - n int; -} - const ( mod = 65521; - maxIter = 5552; // max mod-free iterations before would overflow uint32 ) +// 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; +} + // 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; } diff --git a/src/lib/hash/adler32_test.go b/src/lib/hash/adler32_test.go index 97b918f1316..6647ab18599 100644 --- a/src/lib/hash/adler32_test.go +++ b/src/lib/hash/adler32_test.go @@ -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) {