~john-koepi/ubuntu/trusty/golang/default

« back to all changes in this revision

Viewing changes to src/pkg/crypto/md5/md5.go

  • Committer: Bazaar Package Importer
  • Author(s): Ondřej Surý
  • Date: 2011-04-20 17:36:48 UTC
  • Revision ID: james.westby@ubuntu.com-20110420173648-ifergoxyrm832trd
Tags: upstream-2011.03.07.1
Import upstream version 2011.03.07.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2009 The Go Authors. All rights reserved.
 
2
// Use of this source code is governed by a BSD-style
 
3
// license that can be found in the LICENSE file.
 
4
 
 
5
// This package implements the MD5 hash algorithm as defined in RFC 1321.
 
6
package md5
 
7
 
 
8
import (
 
9
        "crypto"
 
10
        "hash"
 
11
        "os"
 
12
)
 
13
 
 
14
func init() {
 
15
        crypto.RegisterHash(crypto.MD5, New)
 
16
}
 
17
 
 
18
// The size of an MD5 checksum in bytes.
 
19
const Size = 16
 
20
 
 
21
const (
 
22
        _Chunk = 64
 
23
        _Init0 = 0x67452301
 
24
        _Init1 = 0xEFCDAB89
 
25
        _Init2 = 0x98BADCFE
 
26
        _Init3 = 0x10325476
 
27
)
 
28
 
 
29
// digest represents the partial evaluation of a checksum.
 
30
type digest struct {
 
31
        s   [4]uint32
 
32
        x   [_Chunk]byte
 
33
        nx  int
 
34
        len uint64
 
35
}
 
36
 
 
37
func (d *digest) Reset() {
 
38
        d.s[0] = _Init0
 
39
        d.s[1] = _Init1
 
40
        d.s[2] = _Init2
 
41
        d.s[3] = _Init3
 
42
        d.nx = 0
 
43
        d.len = 0
 
44
}
 
45
 
 
46
// New returns a new hash.Hash computing the MD5 checksum.
 
47
func New() hash.Hash {
 
48
        d := new(digest)
 
49
        d.Reset()
 
50
        return d
 
51
}
 
52
 
 
53
func (d *digest) Size() int { return Size }
 
54
 
 
55
func (d *digest) Write(p []byte) (nn int, err os.Error) {
 
56
        nn = len(p)
 
57
        d.len += uint64(nn)
 
58
        if d.nx > 0 {
 
59
                n := len(p)
 
60
                if n > _Chunk-d.nx {
 
61
                        n = _Chunk - d.nx
 
62
                }
 
63
                for i := 0; i < n; i++ {
 
64
                        d.x[d.nx+i] = p[i]
 
65
                }
 
66
                d.nx += n
 
67
                if d.nx == _Chunk {
 
68
                        _Block(d, d.x[0:])
 
69
                        d.nx = 0
 
70
                }
 
71
                p = p[n:]
 
72
        }
 
73
        n := _Block(d, p)
 
74
        p = p[n:]
 
75
        if len(p) > 0 {
 
76
                d.nx = copy(d.x[:], p)
 
77
        }
 
78
        return
 
79
}
 
80
 
 
81
func (d0 *digest) Sum() []byte {
 
82
        // Make a copy of d0 so that caller can keep writing and summing.
 
83
        d := new(digest)
 
84
        *d = *d0
 
85
 
 
86
        // Padding.  Add a 1 bit and 0 bits until 56 bytes mod 64.
 
87
        len := d.len
 
88
        var tmp [64]byte
 
89
        tmp[0] = 0x80
 
90
        if len%64 < 56 {
 
91
                d.Write(tmp[0 : 56-len%64])
 
92
        } else {
 
93
                d.Write(tmp[0 : 64+56-len%64])
 
94
        }
 
95
 
 
96
        // Length in bits.
 
97
        len <<= 3
 
98
        for i := uint(0); i < 8; i++ {
 
99
                tmp[i] = byte(len >> (8 * i))
 
100
        }
 
101
        d.Write(tmp[0:8])
 
102
 
 
103
        if d.nx != 0 {
 
104
                panic("d.nx != 0")
 
105
        }
 
106
 
 
107
        p := make([]byte, 16)
 
108
        j := 0
 
109
        for _, s := range d.s {
 
110
                p[j+0] = byte(s >> 0)
 
111
                p[j+1] = byte(s >> 8)
 
112
                p[j+2] = byte(s >> 16)
 
113
                p[j+3] = byte(s >> 24)
 
114
                j += 4
 
115
        }
 
116
        return p
 
117
}