blob: 426f961b88d79809c973fdd69d057b688603732d [file] [log] [blame]
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Adler-32 checksum.
// Defined in RFC 1950:
// Adler-32 is composed of two sums accumulated per byte: s1 is
// the sum of all bytes, s2 is the sum of all s1 values. Both sums
// are done modulo 65521. s1 is initialized to 1, s2 to zero. The
// Adler-32 checksum is stored as s2*65536 + s1 in most-
// significant-byte first (network) order.
package adler32
import "os"
export type Digest struct {
a, b uint32;
n int;
}
const Mod = 65521;
const Maxiter = 5552; // max mod-free iterations before would overflow uint32
export func NewDigest() *Digest {
return &Digest{1, 0, 0};
}
func (d *Digest) Write(p *[]byte) (nn int, err *os.Error) {
a, b, n := d.a, d.b, d.n;
for i := 0; i < len(p); i++ {
a += uint32(p[i]);
b += a;
n++;
if n == Maxiter {
a %= Mod;
b %= Mod;
n = 0;
}
}
d.a, d.b, d.n = a, b, n;
return len(p), nil
}
func (d *Digest) Sum32() uint32 {
a, b := d.a, d.b;
if a >= Mod || b >= Mod {
a %= Mod;
b %= Mod;
}
return b<<16 | a;
}
func (d *Digest) Sum() *[]byte {
p := new([]byte, 4);
s := d.Sum32();
p[0] = byte(s>>24);
p[1] = byte(s>>16);
p[2] = byte(s>>8);
p[3] = byte(s);
return p;
}