Commit 1910a7c5 authored by Rob Pike's avatar Rob Pike

document hash

R=rsc
DELTA=50  (33 added, 4 deleted, 13 changed)
OCL=25878
CL=25887
parent c5560d3a
...@@ -2,41 +2,44 @@ ...@@ -2,41 +2,44 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Adler-32 checksum. // This package implements the Adler-32 checksum.
// Defined in RFC 1950: // Defined in RFC 1950:
// Adler-32 is composed of two sums accumulated per byte: s1 is // 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 // 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 // are done modulo 65521. s1 is initialized to 1, s2 to zero. The
// Adler-32 checksum is stored as s2*65536 + s1 in most- // Adler-32 checksum is stored as s2*65536 + s1 in most-
// significant-byte first (network) order. // significant-byte first (network) order.
package adler32 package adler32
import "os" import "os"
// Digest represents the partial evaluation of a checksum.
type Digest struct { type Digest struct {
a, b uint32; a, b uint32;
n int; n int;
} }
const ( const (
_Mod = 65521; mod = 65521;
_MaxIter = 5552; // max mod-free iterations before would overflow uint32 maxIter = 5552; // max mod-free iterations before would overflow uint32
) )
// NewDigest creates a new Digest.
func NewDigest() *Digest { func NewDigest() *Digest {
return &Digest{1, 0, 0}; return &Digest{1, 0, 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) { func (d *Digest) Write(p []byte) (nn int, err *os.Error) {
a, b, n := d.a, d.b, d.n; a, b, n := d.a, d.b, d.n;
for i := 0; i < len(p); i++ { for i := 0; i < len(p); i++ {
a += uint32(p[i]); a += uint32(p[i]);
b += a; b += a;
n++; n++;
if n == _MaxIter { if n == maxIter {
a %= _Mod; a %= mod;
b %= _Mod; b %= mod;
n = 0; n = 0;
} }
} }
...@@ -44,15 +47,18 @@ func (d *Digest) Write(p []byte) (nn int, err *os.Error) { ...@@ -44,15 +47,18 @@ func (d *Digest) Write(p []byte) (nn int, err *os.Error) {
return len(p), nil return len(p), nil
} }
// Sum32 returns the 32-bit Adler-32 checksum of the data written to the Digest.
func (d *Digest) Sum32() uint32 { func (d *Digest) Sum32() uint32 {
a, b := d.a, d.b; a, b := d.a, d.b;
if a >= _Mod || b >= _Mod { if a >= mod || b >= mod {
a %= _Mod; a %= mod;
b %= _Mod; b %= mod;
} }
return b<<16 | a; return b<<16 | a;
} }
// Sum returns the 32-bit Adler-32 checksum of the data written to the Digest
// in the form of an array of 4 bytes in big-endian order.
func (d *Digest) Sum() []byte { func (d *Digest) Sum() []byte {
p := make([]byte, 4); p := make([]byte, 4);
s := d.Sum32(); s := d.Sum32();
......
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// CRC-32 checksum. // This package implements the 32-bit cyclic redundancy check, or CRC-32, checksum.
// http://en.wikipedia.org/wiki/Cyclic_redundancy_check for links // See http://en.wikipedia.org/wiki/Cyclic_redundancy_check for information.
package crc32 package crc32
import "os" import "os"
// Predefined polynomials.
const ( const (
// Far and away the most common CRC-32 polynomial. // Far and away the most common CRC-32 polynomial.
// Used by ethernet (IEEE 802.3), v.42, fddi, gzip, zip, png, mpeg-2, ... // Used by ethernet (IEEE 802.3), v.42, fddi, gzip, zip, png, mpeg-2, ...
...@@ -25,9 +25,11 @@ const ( ...@@ -25,9 +25,11 @@ const (
Koopman = 0xeb31d82e; Koopman = 0xeb31d82e;
) )
// Table is a 256-word table representing the polynomial for efficient processing.
// TODO(rsc): Change to [256]uint32 once 6g can handle it. // TODO(rsc): Change to [256]uint32 once 6g can handle it.
type Table []uint32 type Table []uint32
// MakeTable returns the Table constructed from the specified polynomial.
func MakeTable(poly uint32) Table { func MakeTable(poly uint32) Table {
t := make(Table, 256); t := make(Table, 256);
for i := 0; i < 256; i++ { for i := 0; i < 256; i++ {
...@@ -44,21 +46,29 @@ func MakeTable(poly uint32) Table { ...@@ -44,21 +46,29 @@ func MakeTable(poly uint32) Table {
return t; return t;
} }
// IEEETable is the table for the IEEE polynomial.
var IEEETable = MakeTable(IEEE); var IEEETable = MakeTable(IEEE);
// Digest represents the partial evaluation of a checksum.
type Digest struct { type Digest struct {
crc uint32; crc uint32;
tab Table; tab Table;
} }
// NewDigest creates a new Digest for the checksum based on
// the polynomial represented by the Table.
func NewDigest(tab Table) *Digest { func NewDigest(tab Table) *Digest {
return &Digest{0, tab}; return &Digest{0, tab};
} }
// NewIEEEDigest creates a new Digest for the checksum based on
// the IEEE polynomial.
func NewIEEEDigest() *Digest { func NewIEEEDigest() *Digest {
return NewDigest(IEEETable); return NewDigest(IEEETable);
} }
// 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) (n int, err *os.Error) { func (d *Digest) Write(p []byte) (n int, err *os.Error) {
crc := d.crc ^ 0xFFFFFFFF; crc := d.crc ^ 0xFFFFFFFF;
tab := d.tab; tab := d.tab;
...@@ -69,10 +79,13 @@ func (d *Digest) Write(p []byte) (n int, err *os.Error) { ...@@ -69,10 +79,13 @@ func (d *Digest) Write(p []byte) (n int, err *os.Error) {
return len(p), nil; return len(p), nil;
} }
// Sum32 returns the CRC-32 checksum of the data written to the Digest.
func (d *Digest) Sum32() uint32 { func (d *Digest) Sum32() uint32 {
return d.crc return d.crc
} }
// Sum returns the CRC-32 checksum of the data written to the Digest
// in the form of an array of 4 bytes in big-endian order.
func (d *Digest) Sum() []byte { func (d *Digest) Sum() []byte {
p := make([]byte, 4); p := make([]byte, 4);
s := d.Sum32(); s := d.Sum32();
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// MD5 hash algorithm. See RFC 1321. // This package implements the MD5 hash algorithm as defined in RFC 1321.
package md5 package md5
import "os" import "os"
...@@ -17,6 +16,7 @@ const ( ...@@ -17,6 +16,7 @@ const (
_Init3 = 0x10325476; _Init3 = 0x10325476;
) )
// Digest represents the partial evaluation of a checksum.
type Digest struct { type Digest struct {
s [4]uint32; s [4]uint32;
x [_Chunk]byte; x [_Chunk]byte;
...@@ -24,6 +24,7 @@ type Digest struct { ...@@ -24,6 +24,7 @@ type Digest struct {
len uint64; len uint64;
} }
// NewDigest creates a new Digest.
func NewDigest() *Digest { func NewDigest() *Digest {
d := new(Digest); d := new(Digest);
d.s[0] = _Init0; d.s[0] = _Init0;
...@@ -35,6 +36,8 @@ func NewDigest() *Digest { ...@@ -35,6 +36,8 @@ func NewDigest() *Digest {
func _Block(dig *Digest, p []byte) int func _Block(dig *Digest, p []byte) int
// 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) { func (d *Digest) Write(p []byte) (nn int, err *os.Error) {
nn = len(p); nn = len(p);
d.len += uint64(nn); d.len += uint64(nn);
...@@ -64,6 +67,8 @@ func (d *Digest) Write(p []byte) (nn int, err *os.Error) { ...@@ -64,6 +67,8 @@ func (d *Digest) Write(p []byte) (nn int, err *os.Error) {
return; return;
} }
// Sum returns the MD5 checksum of the data written to the Digest
// in the form of an array of 16 bytes in big-endian order.
func (d *Digest) Sum() []byte { func (d *Digest) Sum() []byte {
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
len := d.len; len := d.len;
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// SHA1 hash algorithm. See RFC 3174. // This package implements the SHA1 hash algorithm as defined in RFC 3174.
package sha1 package sha1
import "os" import "os"
...@@ -18,6 +17,7 @@ const ( ...@@ -18,6 +17,7 @@ const (
_Init4 = 0xC3D2E1F0; _Init4 = 0xC3D2E1F0;
) )
// Digest represents the partial evaluation of a checksum.
type Digest struct { type Digest struct {
h [5]uint32; h [5]uint32;
x [_Chunk]byte; x [_Chunk]byte;
...@@ -25,6 +25,7 @@ type Digest struct { ...@@ -25,6 +25,7 @@ type Digest struct {
len uint64; len uint64;
} }
// NewDigest creates a new Digest.
func NewDigest() *Digest { func NewDigest() *Digest {
d := new(Digest); d := new(Digest);
d.h[0] = _Init0; d.h[0] = _Init0;
...@@ -37,6 +38,8 @@ func NewDigest() *Digest { ...@@ -37,6 +38,8 @@ func NewDigest() *Digest {
func _Block(dig *Digest, p []byte) int func _Block(dig *Digest, p []byte) int
// 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) { func (d *Digest) Write(p []byte) (nn int, err *os.Error) {
nn = len(p); nn = len(p);
d.len += uint64(nn); d.len += uint64(nn);
...@@ -66,6 +69,8 @@ func (d *Digest) Write(p []byte) (nn int, err *os.Error) { ...@@ -66,6 +69,8 @@ func (d *Digest) Write(p []byte) (nn int, err *os.Error) {
return; return;
} }
// Sum returns the SHA-1 checksum of the data written to the Digest
// in the form of an array of 20 bytes in big-endian order.
func (d *Digest) Sum() []byte { func (d *Digest) Sum() []byte {
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
len := d.len; len := d.len;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment