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