...
1
2
3
4
5
6
7
8
9
10
11
12
13
14 package adler32
15
16 import (
17 "errors"
18 "hash"
19 )
20
21 const (
22
23 mod = 65521
24
25
26
27 nmax = 5552
28 )
29
30
31 const Size = 4
32
33
34
35 type digest uint32
36
37 func (d *digest) Reset() { *d = 1 }
38
39
40
41
42
43
44 func New() hash.Hash32 {
45 d := new(digest)
46 d.Reset()
47 return d
48 }
49
50 func (d *digest) Size() int { return Size }
51
52 func (d *digest) BlockSize() int { return 4 }
53
54 const (
55 magic = "adl\x01"
56 marshaledSize = len(magic) + 4
57 )
58
59 func (d *digest) MarshalBinary() ([]byte, error) {
60 b := make([]byte, 0, marshaledSize)
61 b = append(b, magic...)
62 b = appendUint32(b, uint32(*d))
63 return b, nil
64 }
65
66 func (d *digest) UnmarshalBinary(b []byte) error {
67 if len(b) < len(magic) || string(b[:len(magic)]) != magic {
68 return errors.New("hash/adler32: invalid hash state identifier")
69 }
70 if len(b) != marshaledSize {
71 return errors.New("hash/adler32: invalid hash state size")
72 }
73 *d = digest(readUint32(b[len(magic):]))
74 return nil
75 }
76
77
78
79 func appendUint32(b []byte, x uint32) []byte {
80 return append(b,
81 byte(x>>24),
82 byte(x>>16),
83 byte(x>>8),
84 byte(x),
85 )
86 }
87
88
89
90 func readUint32(b []byte) uint32 {
91 _ = b[3]
92 return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
93 }
94
95
96 func update(d digest, p []byte) digest {
97 s1, s2 := uint32(d&0xffff), uint32(d>>16)
98 for len(p) > 0 {
99 var q []byte
100 if len(p) > nmax {
101 p, q = p[:nmax], p[nmax:]
102 }
103 for len(p) >= 4 {
104 s1 += uint32(p[0])
105 s2 += s1
106 s1 += uint32(p[1])
107 s2 += s1
108 s1 += uint32(p[2])
109 s2 += s1
110 s1 += uint32(p[3])
111 s2 += s1
112 p = p[4:]
113 }
114 for _, x := range p {
115 s1 += uint32(x)
116 s2 += s1
117 }
118 s1 %= mod
119 s2 %= mod
120 p = q
121 }
122 return digest(s2<<16 | s1)
123 }
124
125 func (d *digest) Write(p []byte) (nn int, err error) {
126 *d = update(*d, p)
127 return len(p), nil
128 }
129
130 func (d *digest) Sum32() uint32 { return uint32(*d) }
131
132 func (d *digest) Sum(in []byte) []byte {
133 s := uint32(*d)
134 return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
135 }
136
137
138 func Checksum(data []byte) uint32 { return uint32(update(1, data)) }
139
View as plain text