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) AppendBinary(b []byte) ([]byte, error) {
61 b = append(b, magic...)
62 b = byteorder.BEAppendUint32(b, uint32(*d))
63 return b, nil
64 }
65
66 func (d *digest) MarshalBinary() ([]byte, error) {
67 return d.AppendBinary(make([]byte, 0, marshaledSize))
68 }
69
70 func (d *digest) UnmarshalBinary(b []byte) error {
71 if len(b) < len(magic) || string(b[:len(magic)]) != magic {
72 return errors.New("hash/adler32: invalid hash state identifier")
73 }
74 if len(b) != marshaledSize {
75 return errors.New("hash/adler32: invalid hash state size")
76 }
77 *d = digest(byteorder.BEUint32(b[len(magic):]))
78 return nil
79 }
80
81 func (d *digest) Clone() (hash.Cloner, error) {
82 r := *d
83 return &r, nil
84 }
85
86
87 func update(d digest, p []byte) digest {
88 if haveSIMD && len(p) >= minSIMD {
89 return updateSIMD(d, p)
90 }
91 return updateGeneric(d, p)
92 }
93
94
95
96
97 func updateGeneric(d digest, p []byte) digest {
98 s1, s2 := uint32(d&0xffff), uint32(d>>16)
99 for len(p) > 0 {
100 var q []byte
101 if len(p) > nmax {
102 p, q = p[:nmax], p[nmax:]
103 }
104 for len(p) >= 4 {
105 s1 += uint32(p[0])
106 s2 += s1
107 s1 += uint32(p[1])
108 s2 += s1
109 s1 += uint32(p[2])
110 s2 += s1
111 s1 += uint32(p[3])
112 s2 += s1
113 p = p[4:]
114 }
115 for _, x := range p {
116 s1 += uint32(x)
117 s2 += s1
118 }
119 s1 %= mod
120 s2 %= mod
121 p = q
122 }
123 return digest(s2<<16 | s1)
124 }
125
126 func (d *digest) Write(p []byte) (nn int, err error) {
127 *d = update(*d, p)
128 return len(p), nil
129 }
130
131 func (d *digest) Sum32() uint32 { return uint32(*d) }
132
133 func (d *digest) Sum(in []byte) []byte {
134 s := uint32(*d)
135 return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
136 }
137
138
139 func Checksum(data []byte) uint32 { return uint32(update(1, data)) }
140
View as plain text