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
82 func update(d digest, p []byte) digest {
83 s1, s2 := uint32(d&0xffff), uint32(d>>16)
84 for len(p) > 0 {
85 var q []byte
86 if len(p) > nmax {
87 p, q = p[:nmax], p[nmax:]
88 }
89 for len(p) >= 4 {
90 s1 += uint32(p[0])
91 s2 += s1
92 s1 += uint32(p[1])
93 s2 += s1
94 s1 += uint32(p[2])
95 s2 += s1
96 s1 += uint32(p[3])
97 s2 += s1
98 p = p[4:]
99 }
100 for _, x := range p {
101 s1 += uint32(x)
102 s2 += s1
103 }
104 s1 %= mod
105 s2 %= mod
106 p = q
107 }
108 return digest(s2<<16 | s1)
109 }
110
111 func (d *digest) Write(p []byte) (nn int, err error) {
112 *d = update(*d, p)
113 return len(p), nil
114 }
115
116 func (d *digest) Sum32() uint32 { return uint32(*d) }
117
118 func (d *digest) Sum(in []byte) []byte {
119 s := uint32(*d)
120 return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
121 }
122
123
124 func Checksum(data []byte) uint32 { return uint32(update(1, data)) }
125
View as plain text