generated from soypat/go-module-template
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathcrc.go
84 lines (76 loc) · 1.98 KB
/
crc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package eth
import (
"encoding/binary"
)
// CRC791 function as defined by RFC 791. The Checksum field for TCP+IP
// is the 16-bit ones' complement of the ones' complement sum of
// all 16-bit words in the header. In case of uneven number of octet the
// last word is LSB padded with zeros.
//
// The zero value of CRC791 is ready to use.
type CRC791 struct {
sum uint32
excedent uint8
needPad bool
}
// Write adds the bytes in p to the running checksum.
func (c *CRC791) Write(buff []byte) (n int, err error) {
if len(buff) == 0 {
return 0, nil
}
if c.needPad {
c.sum += uint32(c.excedent)<<8 + uint32(buff[0])
buff = buff[1:]
c.excedent = 0
c.needPad = false
if len(buff) == 0 {
return 1, nil
}
}
count := len(buff)
for count > 1 {
c.sum += uint32(binary.BigEndian.Uint16(buff[len(buff)-count:]))
count -= 2
}
if count != 0 {
c.excedent = buff[len(buff)-1]
c.needPad = true
}
return len(buff), nil
}
// Add16 adds value to the running checksum interpreted as BigEndian (network order).
func (c *CRC791) AddUint32(value uint32) {
c.AddUint16(uint16(value >> 16))
c.AddUint16(uint16(value))
}
// Add16 adds value to the running checksum interpreted as BigEndian (network order).
func (c *CRC791) AddUint16(value uint16) {
if c.needPad {
c.sum += uint32(c.excedent)<<8 | uint32(value>>8)
c.excedent = byte(value)
} else {
c.sum += uint32(value)
}
}
// Add16 adds value to the running checksum interpreted as BigEndian (network order).
func (c *CRC791) AddUint8(value uint8) {
if c.needPad {
c.sum += uint32(c.excedent)<<8 | uint32(value)
} else {
c.excedent = value
}
c.needPad = !c.needPad
}
// Sum16 calculates the checksum with the data written to c thus far.
func (c *CRC791) Sum16() uint16 {
sum := c.sum
if c.needPad {
sum += uint32(c.excedent) << 8
}
for sum>>16 != 0 {
sum = (sum & 0xffff) + (sum >> 16)
}
return uint16(^sum)
}
// Reset zeros out the CRC791, resetting it to the initial state.
func (c *CRC791) Reset() { *c = CRC791{} }