-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbitwise.go
54 lines (48 loc) · 1.33 KB
/
bitwise.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
package crcutil
import (
"unsafe"
)
// BitwiseUpdateFn returns a function that returns the result of
// adding the bits defined by data and dataWidth into the crc.
// The actual function returned depends on the polynomial's
// representation (normal or reversed form).
func BitwiseUpdateFn[T, D Word](poly *Poly[T]) func(poly *Poly[T], crc T, data D, dataWidth int) T {
if !poly.Reversed {
return updateBitwiseNormal[T, D]
}
return updateBitwiseReversed[T, D]
}
func UpdateBitwise[T, D Word](poly *Poly[T], crc T, data D, dataWidth int) T {
return BitwiseUpdateFn[T, D](poly)(poly, crc, data, dataWidth)
}
func updateBitwiseNormal[T, D Word](poly *Poly[T], crc T, data D, dataWidth int) T {
msb := T(1) << (poly.Width - 1)
msbData := D(1) << (dataWidth - 1)
for i := msbData; i > 0; i >>= 1 {
bit := crc & msb
if (data & i) != 0 {
bit ^= msb
}
if bit != 0 {
crc = (crc << 1) ^ poly.Word
} else {
crc <<= 1
}
}
return crc & poly.mask()
}
func updateBitwiseReversed[T, D Word](poly *Poly[T], crcIn T, data D, dataWidth int) T {
if unsafe.Sizeof(crcIn) > unsafe.Sizeof(data) {
panic("D must be at least as wide as T")
}
mask := (D(1) << poly.Width) - 1
crc := D(crcIn) ^ data
for i := 0; i < dataWidth; i++ {
if crc&1 == 1 {
crc = (crc >> 1) ^ D(poly.Word)
} else {
crc >>= 1
}
}
return T(crc & mask)
}