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