* new package hash defining interfaces Hash and Hash32.
* adler32 and crc32 return Hash32 instead of specific types.
* adler32 and crc32 provide non-allocating methods for single slices.
* sha1 and md5 move to crypto, return Hash.
* sum.go, a simple test program, moves to /usr/rsc.
* refresh Make.deps
R=r
DELTA=1908 (935 added, 923 deleted, 50 changed)
OCL=29095
CL=29135
container/vector.install:
crypto/aes.install: os.install
crypto/block.install: fmt.install io.install os.install
+crypto/md5.install: hash.install os.install
+crypto/sha1.install: hash.install os.install
exec.install: os.install strings.install
exvar.install: fmt.install http.install io.install log.install strconv.install sync.install
flag.install: fmt.install os.install strconv.install
go/parser.install: container/vector.install fmt.install go/ast.install go/scanner.install go/token.install io.install os.install
go/scanner.install: go/token.install strconv.install unicode.install utf8.install
go/token.install: strconv.install
-hash/adler32.install: os.install
-hash/crc32.install: os.install
-hash/md5.install: os.install
-hash/sha1.install: os.install
-hash/sum.install: flag.install fmt.install hash/adler32.install hash/crc32.install hash/md5.install hash/sha1.install io.install os.install
+hash.install: io.install
+hash/adler32.install: hash.install os.install
+hash/crc32.install: hash.install os.install
http.install: bufio.install fmt.install io.install log.install net.install os.install path.install strconv.install strings.install utf8.install
io.install: os.install sync.install
json.install: container/vector.install fmt.install io.install math.install reflect.install strconv.install strings.install utf8.install
container/vector\
crypto/aes\
crypto/block\
+ crypto/md5\
+ crypto/sha1\
exec\
exvar\
flag\
go/parser\
go/scanner\
go/token\
+ hash\
hash/adler32\
hash/crc32\
- hash/md5\
- hash/sha1\
- hash/sum\
http\
io\
json\
bufio\
container/vector\
crypto/aes\
+ crypto/block\
+ crypto/md5\
+ crypto/sha1\
exec\
exvar\
flag\
go/scanner\
hash/adler32\
hash/crc32\
- hash/md5\
- hash/sha1\
http\
io\
json\
# DO NOT EDIT. Automatically generated by gobuild.
# gobuild -m >Makefile
-D=/hash/
+D=/crypto/
O_arm=5
O_amd64=6
// This package implements the MD5 hash algorithm as defined in RFC 1321.
package md5
-import "os"
+import (
+ "hash";
+ "os";
+)
+
+// The size of an MD5 checksum in bytes.
+const Size = 16;
const (
_Chunk = 64;
_Init3 = 0x10325476;
)
-// Digest represents the partial evaluation of a checksum.
-type Digest struct {
+// digest represents the partial evaluation of a checksum.
+type digest struct {
s [4]uint32;
x [_Chunk]byte;
nx int;
len uint64;
}
-// NewDigest creates a new Digest.
-func NewDigest() *Digest {
- d := new(Digest);
+func (d *digest) Reset() {
d.s[0] = _Init0;
d.s[1] = _Init1;
d.s[2] = _Init2;
d.s[3] = _Init3;
+}
+
+// New returns a Hash computing the SHA1 checksum.
+func New() hash.Hash {
+ d := new(digest);
+ d.Reset();
return d;
}
-func _Block(dig *Digest, p []byte) int
+func (d *digest) Size() int {
+ return Size;
+}
+
+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);
d.len += uint64(nn);
if d.nx > 0 {
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.
len := d.len;
var tmp [64]byte;
import (
"fmt";
- "hash/md5";
+ "crypto/md5";
"io";
"testing";
)
func TestGolden(t *testing.T) {
for i := 0; i < len(golden); i++ {
g := golden[i];
- c := NewDigest();
+ c := New();
io.WriteString(c, g.in);
s := fmt.Sprintf("%x", c.Sum());
if s != g.out {
package md5
-import "hash/md5"
+import "crypto/md5"
// table[i] = int((1<<32) * abs(sin(i+1 radians))).
var table = []uint32 {
var shift3 = []uint { 4, 11, 16, 23 };
var shift4 = []uint { 6, 10, 15, 21 };
-func _Block(dig *Digest, p []byte) int {
+func _Block(dig *digest, p []byte) int {
a := dig.s[0];
b := dig.s[1];
c := dig.s[2];
# DO NOT EDIT. Automatically generated by gobuild.
# gobuild -m >Makefile
-D=/hash/
+D=/crypto/
O_arm=5
O_amd64=6
// This package implements the SHA1 hash algorithm as defined in RFC 3174.
package sha1
-import "os"
+import (
+ "hash";
+ "os";
+)
+
+// The size of a SHA1 checksum in bytes.
+const Size = 20;
const (
_Chunk = 64;
_Init4 = 0xC3D2E1F0;
)
-// Digest represents the partial evaluation of a checksum.
-type Digest struct {
+// digest represents the partial evaluation of a checksum.
+type digest struct {
h [5]uint32;
x [_Chunk]byte;
nx int;
len uint64;
}
-// NewDigest creates a new Digest.
-func NewDigest() *Digest {
- d := new(Digest);
+func (d *digest) Reset() {
d.h[0] = _Init0;
d.h[1] = _Init1;
d.h[2] = _Init2;
d.h[3] = _Init3;
d.h[4] = _Init4;
+}
+
+// New returns a Hash computing the SHA1 checksum.
+func New() hash.Hash {
+ d := new(digest);
+ d.Reset();
return d;
}
-func _Block(dig *Digest, p []byte) int
+func (d *digest) Size() int {
+ return Size;
+}
+
+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);
d.len += uint64(nn);
if d.nx > 0 {
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.
len := d.len;
var tmp [64]byte;
import (
"fmt";
- "hash/sha1";
+ "crypto/sha1";
"io";
"testing";
)
func TestGolden(t *testing.T) {
for i := 0; i < len(golden); i++ {
g := golden[i];
- c := NewDigest();
+ c := New();
io.WriteString(c, g.in);
s := fmt.Sprintf("%x", c.Sum());
if s != g.out {
package sha1
-import "hash/sha1"
+import "crypto/sha1"
const (
_K0 = 0x5A827999;
_K3 = 0xCA62C1D6;
)
-func _Block(dig *Digest, p []byte) int {
+func _Block(dig *digest, p []byte) int {
var w [80]uint32;
n := 0;
// significant-byte first (network) order.
package adler32
-import "os"
+import (
+ "hash";
+ "os";
+)
const (
mod = 65521;
)
-// Digest represents the partial evaluation of a checksum.
-type Digest struct {
+// The size of an Adler-32 checksum in bytes.
+const Size = 4;
+
+// 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};
+func (d *digest) Reset() {
+ d.a, d.b = 1, 0;
+}
+
+// New returns a new Hash32 computing the Adler-32 checksum.
+func New() hash.Hash32 {
+ d := new(digest);
+ d.Reset();
+ return d;
+}
+
+func (d *digest) Size() int {
+ return Size;
}
-// 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 := d.a, d.b;
+// Add p to the running checksum a, b.
+func update(a, b uint32, p []byte) (aa, bb uint32) {
for i := 0; i < len(p); i++ {
a += uint32(p[i]);
b += a;
// invariant: a + b + 255 <= 2 * b + 255 <= 0xffffffff
}
}
- d.a, d.b = a, b;
- return len(p), nil
+ return a, b;
}
-// 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;
+// Return the 32-bit checksum corresponding to a, b.
+func finish(a, b uint32) uint32 {
if b >= mod {
a %= mod;
b %= mod;
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) Write(p []byte) (nn int, err os.Error) {
+ d.a, d.b = update(d.a, d.b, p);
+ return len(p), nil;
+}
+
+func (d *digest) Sum32() uint32 {
+ return finish(d.a, d.b);
+}
+
+func (d *digest) Sum() []byte {
p := make([]byte, 4);
s := d.Sum32();
p[0] = byte(s>>24);
p[3] = byte(s);
return p;
}
+
+// Checksum returns the Adler-32 checksum of data.
+func Checksum(data []byte) uint32 {
+ return finish(update(1, 0, data));
+}
func TestGolden(t *testing.T) {
for i := 0; i < len(golden); i++ {
g := golden[i];
- c := NewDigest();
+ c := New();
io.WriteString(c, g.in);
s := c.Sum32();
if s != g.out {
// See http://en.wikipedia.org/wiki/Cyclic_redundancy_check for information.
package crc32
-import "os"
+import (
+ "hash";
+ "os";
+)
+
+// The size of a CRC-32 checksum in bytes.
+const Size = 4;
// Predefined polynomials.
const (
)
// Table is a 256-word table representing the polynomial for efficient processing.
-// TODO(rsc): Change to [256]uint32 once 6g can handle it.
-type Table []uint32
+type Table [256]uint32
// MakeTable returns the Table constructed from the specified polynomial.
-func MakeTable(poly uint32) Table {
- t := make(Table, 256);
+func MakeTable(poly uint32) *Table {
+ t := new(Table);
for i := 0; i < 256; i++ {
crc := uint32(i);
for j := 0; j < 8; j++ {
// IEEETable is the table for the IEEE polynomial.
var IEEETable = MakeTable(IEEE);
-// Digest represents the partial evaluation of a checksum.
-type Digest struct {
+// digest represents the partial evaluation of a checksum.
+type digest struct {
crc uint32;
- tab Table;
+ tab *Table;
+}
+
+// New creates a new Hash computing the CRC-32 checksum
+// using the polynomial represented by the Table.
+func New(tab *Table) hash.Hash32 {
+ return &digest{0, tab};
+}
+
+// NewIEEE creates a new Hash computing the CRC-32 checksum
+// using the IEEE polynomial.
+func NewIEEE() hash.Hash32 {
+ return New(IEEETable);
}
-// NewDigest creates a new Digest for the checksum based on
-// the polynomial represented by the Table.
-func NewDigest(tab Table) *Digest {
- return &Digest{0, tab};
+func (d *digest) Size() int {
+ return Size;
}
-// NewIEEEDigest creates a new Digest for the checksum based on
-// the IEEE polynomial.
-func NewIEEEDigest() *Digest {
- return NewDigest(IEEETable);
+func (d *digest) Reset() {
+ d.crc = 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) (n int, err os.Error) {
- crc := d.crc ^ 0xFFFFFFFF;
- tab := d.tab;
+func update(crc uint32, tab *Table, p []byte) uint32 {
+ crc ^= 0xFFFFFFFF;
for i := 0; i < len(p); i++ {
crc = tab[byte(crc) ^ p[i]] ^ (crc >> 8);
}
- d.crc = crc ^ 0xFFFFFFFF;
+ crc ^= 0xFFFFFFFF;
+ return crc;
+}
+
+func (d *digest) Write(p []byte) (n int, err os.Error) {
+ d.crc = update(d.crc, d.tab, p);
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
}
-// 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);
s := d.Sum32();
p[0] = byte(s>>24);
return p;
}
+// Checksum returns the CRC-32 checksum of data
+// using the polynomial represented by the Table.
+func Checksum(data []byte, tab *Table) uint32 {
+ return update(0, tab, data);
+}
+// ChecksumIEEE returns the CRC-32 checksum of data
+// using the IEEE polynomial.
+func ChecksumIEEE(data []byte) uint32 {
+ return update(0, IEEETable, data);
+}
func TestGolden(t *testing.T) {
for i := 0; i < len(golden); i++ {
g := golden[i];
- c := NewIEEEDigest();
+ c := NewIEEE();
io.WriteString(c, g.in);
s := c.Sum32();
if s != g.out {