]> Cypherpunks repositories - gostls13.git/commitdiff
hash reorg.
authorRuss Cox <rsc@golang.org>
Thu, 21 May 2009 01:16:38 +0000 (18:16 -0700)
committerRuss Cox <rsc@golang.org>
Thu, 21 May 2009 01:16:38 +0000 (18:16 -0700)
* 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

14 files changed:
src/lib/Make.deps
src/lib/Makefile
src/lib/crypto/md5/Makefile [moved from src/lib/hash/md5/Makefile with 98% similarity]
src/lib/crypto/md5/md5.go [moved from src/lib/hash/md5/md5.go with 72% similarity]
src/lib/crypto/md5/md5_test.go [moved from src/lib/hash/md5/md5_test.go with 99% similarity]
src/lib/crypto/md5/md5block.go [moved from src/lib/hash/md5/md5block.go with 98% similarity]
src/lib/crypto/sha1/Makefile [moved from src/lib/hash/sha1/Makefile with 98% similarity]
src/lib/crypto/sha1/sha1.go [moved from src/lib/hash/sha1/sha1.go with 72% similarity]
src/lib/crypto/sha1/sha1_test.go [moved from src/lib/hash/sha1/sha1_test.go with 99% similarity]
src/lib/crypto/sha1/sha1block.go [moved from src/lib/hash/sha1/sha1block.go with 96% similarity]
src/lib/hash/adler32/adler32.go
src/lib/hash/adler32/adler32_test.go
src/lib/hash/crc32/crc32.go
src/lib/hash/crc32/crc32_test.go

index d75dbf22e58d4070ccf0fa6dba08db9838f88bba..30083f2631b744002e74264b2bad737f13a04e8e 100644 (file)
@@ -3,6 +3,8 @@ bufio.install: io.install os.install utf8.install
 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
@@ -12,11 +14,9 @@ go/doc.install: container/vector.install fmt.install go/ast.install go/token.ins
 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
index 75c6758d36abb1c5d8b92134d514e1976717940b..d258e1adbcbd21be329947b8d6852834b4614a6b 100644 (file)
@@ -19,6 +19,8 @@ DIRS=\
        container/vector\
        crypto/aes\
        crypto/block\
+       crypto/md5\
+       crypto/sha1\
        exec\
        exvar\
        flag\
@@ -28,11 +30,9 @@ DIRS=\
        go/parser\
        go/scanner\
        go/token\
+       hash\
        hash/adler32\
        hash/crc32\
-       hash/md5\
-       hash/sha1\
-       hash/sum\
        http\
        io\
        json\
@@ -65,6 +65,9 @@ TEST=\
        bufio\
        container/vector\
        crypto/aes\
+       crypto/block\
+       crypto/md5\
+       crypto/sha1\
        exec\
        exvar\
        flag\
@@ -73,8 +76,6 @@ TEST=\
        go/scanner\
        hash/adler32\
        hash/crc32\
-       hash/md5\
-       hash/sha1\
        http\
        io\
        json\
similarity index 98%
rename from src/lib/hash/md5/Makefile
rename to src/lib/crypto/md5/Makefile
index f9320faaf5b6c747ee3cb4f7da44c61430f05452..8867b84a52ea7ca5792c6b122ace3861d574a34d 100644 (file)
@@ -5,7 +5,7 @@
 # DO NOT EDIT.  Automatically generated by gobuild.
 # gobuild -m >Makefile
 
-D=/hash/
+D=/crypto/
 
 O_arm=5
 O_amd64=6
similarity index 72%
rename from src/lib/hash/md5/md5.go
rename to src/lib/crypto/md5/md5.go
index de8d34d33fb6a015620b386975093638896c1908..f8b8dda2fb973d145b5d8859443079026b66bf7d 100644 (file)
@@ -5,7 +5,13 @@
 // 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;
@@ -16,29 +22,35 @@ const (
        _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 {
@@ -67,9 +79,7 @@ func (d *Digest) Write(p []byte) (nn int, err os.Error) {
        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;
similarity index 99%
rename from src/lib/hash/md5/md5_test.go
rename to src/lib/crypto/md5/md5_test.go
index 80271978d3aaacb5a7e2000c44109218ae228bc3..e557742cc719da65f6efbf2414c0dddd67c2a3a0 100644 (file)
@@ -6,7 +6,7 @@ package md5
 
 import (
        "fmt";
-       "hash/md5";
+       "crypto/md5";
        "io";
        "testing";
 )
@@ -53,7 +53,7 @@ var golden = []md5Test {
 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 {
similarity index 98%
rename from src/lib/hash/md5/md5block.go
rename to src/lib/crypto/md5/md5block.go
index 0fc210a2cfda2a1becd76ad88882ef8db6c3705e..2776c8795c1613e687b15d29380676bbea94e618 100644 (file)
@@ -8,7 +8,7 @@
 
 package md5
 
-import "hash/md5"
+import "crypto/md5"
 
 // table[i] = int((1<<32) * abs(sin(i+1 radians))).
 var table = []uint32 {
@@ -90,7 +90,7 @@ var shift2 = []uint { 5, 9, 14, 20 };
 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];
similarity index 98%
rename from src/lib/hash/sha1/Makefile
rename to src/lib/crypto/sha1/Makefile
index 0f09259b48fa0fd308d60b05cb445bb283971177..f4e1ea0dd53dd7e7399a87c31381415c8281f57c 100644 (file)
@@ -5,7 +5,7 @@
 # DO NOT EDIT.  Automatically generated by gobuild.
 # gobuild -m >Makefile
 
-D=/hash/
+D=/crypto/
 
 O_arm=5
 O_amd64=6
similarity index 72%
rename from src/lib/hash/sha1/sha1.go
rename to src/lib/crypto/sha1/sha1.go
index 2b83eb9b0ca2086968889761e346fd741256bffb..c5f702264f2667eb1ad83b8024dee7263693c8cc 100644 (file)
@@ -5,7 +5,13 @@
 // 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;
@@ -17,30 +23,36 @@ const (
        _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 {
@@ -69,9 +81,7 @@ func (d *Digest) Write(p []byte) (nn int, err os.Error) {
        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;
similarity index 99%
rename from src/lib/hash/sha1/sha1_test.go
rename to src/lib/crypto/sha1/sha1_test.go
index 103b218e9bca5319db8cada545af5aeefb55ff00..3ac9a47ec2a029ef0e4d43209fa8bc432d4651b2 100644 (file)
@@ -8,7 +8,7 @@ package sha1
 
 import (
        "fmt";
-       "hash/sha1";
+       "crypto/sha1";
        "io";
        "testing";
 )
@@ -55,7 +55,7 @@ var golden = []sha1Test {
 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 {
similarity index 96%
rename from src/lib/hash/sha1/sha1block.go
rename to src/lib/crypto/sha1/sha1block.go
index 51bfd6d0924de878909fc2b517ba31116715bafd..01ddd9506ac8d54d7858a228724fcdc3f3ccaec3 100644 (file)
@@ -8,7 +8,7 @@
 
 package sha1
 
-import "hash/sha1"
+import "crypto/sha1"
 
 const (
        _K0 = 0x5A827999;
@@ -17,7 +17,7 @@ const (
        _K3 = 0xCA62C1D6;
 )
 
-func _Block(dig *Digest, p []byte) int {
+func _Block(dig *digest, p []byte) int {
        var w [80]uint32;
 
        n := 0;
index 2b3bd6f85a9614dcf6d3a994335a94ea4ea356b9..fbf9177f895be5906ee4d6c77a5d01e9767e0e4b 100644 (file)
 //     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;
@@ -45,13 +59,11 @@ func (d *Digest) Write(p []byte) (nn int, err os.Error) {
                        // 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;
@@ -59,9 +71,16 @@ func (d *Digest) Sum32() uint32 {
        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);
@@ -70,3 +89,8 @@ func (d *Digest) Sum() []byte {
        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));
+}
index 90c0f6d39e9b05fc548e9012b3c4c24a07e2b98a..ce49a110bb3ff6c495ec62532524e4b7d2868941 100644 (file)
@@ -53,7 +53,7 @@ var golden = []_Adler32Test {
 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 {
index 57fa6af816debc4f35694ef739c3e481d9cd8d2b..7fc3966aea9e755b987a3e7c03c7c8a8fde83e05 100644 (file)
@@ -6,7 +6,13 @@
 // 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 (
@@ -26,12 +32,11 @@ 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++ {
@@ -49,44 +54,51 @@ func MakeTable(poly uint32) Table {
 // 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);
@@ -96,4 +108,14 @@ func (d *Digest) Sum() []byte {
        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);
+}
index 2d675468d0d250581e5f92b090e6dddeed5a6a92..c037da600e13ae8894cb6a64c329cbe02d025b79 100644 (file)
@@ -52,7 +52,7 @@ var golden = []_Crc32Test {
 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 {