229 lines
5.8 KiB
Go
229 lines
5.8 KiB
Go
package message
|
||
|
||
//rssp 协议中crc校验,查表法实现
|
||
|
||
// Crc16Table G(x)=X16+X11+X4+1,计算初始值为0
|
||
var crc16Table []uint32 = nil
|
||
var crc32C1Table []uint32 = nil
|
||
var crc32C2Table []uint32 = nil
|
||
|
||
const (
|
||
RsspCrc16GX uint32 = 0b1_0000_1000_0001_0001 //生成多项式 G(X)=X16+X11+X4+1
|
||
RsspCrc32C1 uint32 = 0x100d4e63 //安全通道1 CRC32生成多项式
|
||
RsspCrc32C2 uint32 = 0x8ce56011 //安全通道1 CRC32生成多项式
|
||
)
|
||
|
||
func CreateRsspCrcTable() {
|
||
if crc16Table == nil {
|
||
var table = make([]uint32, 0, 256)
|
||
for bt := 0x00; bt <= 0xff; bt++ {
|
||
table = append(table, Lookup(uint32(bt), RsspCrc16GX, 16, false))
|
||
}
|
||
crc16Table = table
|
||
}
|
||
if crc32C1Table == nil {
|
||
var table = make([]uint32, 0, 256)
|
||
for bt := 0x00; bt <= 0xff; bt++ {
|
||
table = append(table, Lookup(uint32(bt), RsspCrc32C1, 32, false))
|
||
}
|
||
crc32C1Table = table
|
||
}
|
||
if crc32C2Table == nil {
|
||
var table = make([]uint32, 0, 256)
|
||
for bt := 0x00; bt <= 0xff; bt++ {
|
||
table = append(table, Lookup(uint32(bt), RsspCrc32C2, 32, false))
|
||
}
|
||
crc32C2Table = table
|
||
}
|
||
}
|
||
func RsspCrc16(data []byte) uint16 {
|
||
return uint16(CrcTableBased(data, 16, 0, false, false, 0, crc16Table))
|
||
}
|
||
func RsspC1Crc32(data []byte) uint32 {
|
||
return CrcTableBased(data, 32, 0, false, false, 0, crc32C1Table)
|
||
}
|
||
func RsspC2Crc32(data []byte) uint32 {
|
||
return CrcTableBased(data, 32, 0, false, false, 0, crc32C2Table)
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
|
||
// 反转(0b00001010->0b01010000)
|
||
func reflect(data uint32, width int) uint32 {
|
||
var register1 uint32 = 0
|
||
var significant_mask uint32 = 0xffffffff >> (32 - width)
|
||
var register_msb_mask uint32 = 1 << (width - 1)
|
||
var register_lsb_mask uint32 = 1
|
||
|
||
for i := 0; i < width; i++ {
|
||
need_or := (data>>i)®ister_lsb_mask == register_lsb_mask
|
||
if need_or {
|
||
register1 |= register_msb_mask >> i
|
||
}
|
||
}
|
||
return register1 & significant_mask
|
||
}
|
||
|
||
// Lookup 计算单个数值的crc
|
||
func Lookup(data uint32,
|
||
polynomial uint32,
|
||
width int,
|
||
input_reflected bool) uint32 {
|
||
var register1 uint32 = 0
|
||
var significant_mask uint32 = 0xffffffff >> (32 - width)
|
||
var register_msb_mask uint32 = 1 << (width - 1)
|
||
var register_lsb_mask uint32 = 1
|
||
var byte_msb_mask uint32 = 0x80
|
||
var byte_lsb_mask uint32 = 1
|
||
|
||
if input_reflected {
|
||
polynomial = reflect(polynomial, width)
|
||
}
|
||
|
||
for i := 0; i < 1+(width/8); i++ {
|
||
var byteData uint32 = 0
|
||
|
||
if i < 1 {
|
||
byteData = data
|
||
}
|
||
|
||
for j := 0; j < 8; j++ {
|
||
need_xor := false
|
||
|
||
if input_reflected {
|
||
need_xor = (register1 & register_lsb_mask) == register_lsb_mask
|
||
register1 >>= 1
|
||
|
||
need_or := (byteData & byte_lsb_mask) == byte_lsb_mask
|
||
byteData >>= 1
|
||
|
||
if need_or {
|
||
register1 |= register_msb_mask
|
||
}
|
||
} else {
|
||
need_xor = (register1 & register_msb_mask) == register_msb_mask
|
||
register1 <<= 1
|
||
|
||
need_or := (byteData & byte_msb_mask) == byte_msb_mask
|
||
byteData <<= 1
|
||
|
||
if need_or {
|
||
register1 |= register_lsb_mask
|
||
}
|
||
}
|
||
|
||
if need_xor {
|
||
register1 ^= polynomial
|
||
}
|
||
}
|
||
}
|
||
return register1 & significant_mask
|
||
}
|
||
|
||
// CrcTableBased 查表法计算字节数组的crc
|
||
func CrcTableBased(
|
||
data []byte,
|
||
width int,
|
||
initial_value uint32,
|
||
input_reflected bool,
|
||
result_reflected bool,
|
||
final_xor_value uint32,
|
||
table []uint32) uint32 {
|
||
//
|
||
length := len(data)
|
||
var register1 uint32 = initial_value
|
||
var significant_mask uint32 = 0xffffffff >> (32 - width)
|
||
var register_lsb_mask uint32 = 0xff
|
||
|
||
if input_reflected {
|
||
register1 = reflect(register1, width)
|
||
}
|
||
|
||
for i := 0; i < length; i++ {
|
||
var byteData = uint32(data[i])
|
||
var shift_out uint32 = 0
|
||
|
||
if input_reflected {
|
||
shift_out = register1 & register_lsb_mask
|
||
register1 = (register1 >> 8) ^ table[shift_out^byteData]
|
||
} else {
|
||
shift_out = (register1 >> (width - 8)) & register_lsb_mask
|
||
register1 = (register1 << 8) ^ table[shift_out^byteData]
|
||
}
|
||
}
|
||
|
||
if input_reflected != result_reflected {
|
||
register1 = reflect(register1, width)
|
||
}
|
||
return (register1 ^ final_xor_value) & significant_mask
|
||
}
|
||
|
||
// MSB优先(字节中高位bit即最左侧bit优先)
|
||
func CrcBitOrientedMsbFirst(data []byte, polynomial uint32, width int) uint32 {
|
||
var register1 uint32 = 0
|
||
var significant_mask uint32 = 0xffffffff >> (32 - width)
|
||
var register_msb_mask uint32 = 1 << (width - 1)
|
||
var register_lsb_mask uint32 = 1
|
||
var byte_msb_mask uint32 = 0x80
|
||
length := len(data)
|
||
|
||
for i := 0; i < length+(width/8); i++ {
|
||
var byteData uint32 = 0
|
||
if i < length {
|
||
byteData = uint32(data[i])
|
||
}
|
||
for j := 0; j < 8; j++ {
|
||
need_xor := (register1 & register_msb_mask) == register_msb_mask
|
||
register1 <<= 1
|
||
|
||
need_or := (byteData & byte_msb_mask) == byte_msb_mask
|
||
byteData <<= 1
|
||
|
||
if need_or {
|
||
register1 |= register_lsb_mask
|
||
}
|
||
if need_xor {
|
||
register1 ^= polynomial
|
||
}
|
||
}
|
||
}
|
||
return register1 & significant_mask
|
||
}
|
||
func Crc(data []byte,
|
||
polynomial uint32,
|
||
width int,
|
||
initial_value uint32,
|
||
input_reflected bool,
|
||
result_reflected bool,
|
||
final_xor_value uint32) uint32 {
|
||
length := len(data)
|
||
var register1 uint32 = initial_value
|
||
var significant_mask uint32 = 0xffffffff >> (32 - width)
|
||
var register_lsb_mask uint32 = 0xff
|
||
|
||
if input_reflected {
|
||
register1 = reflect(register1, width)
|
||
}
|
||
|
||
for i := 0; i < length; i++ {
|
||
var byteData uint32 = uint32(data[i])
|
||
var shift_out uint32 = 0
|
||
var value uint32 = 0
|
||
|
||
if input_reflected {
|
||
shift_out = register1 & register_lsb_mask
|
||
value = Lookup(shift_out^byteData, polynomial, width, input_reflected)
|
||
register1 = (register1 >> 8) ^ value
|
||
} else {
|
||
shift_out = (register1 >> (width - 8)) & register_lsb_mask
|
||
value = Lookup(shift_out^byteData, polynomial, width, input_reflected)
|
||
register1 = (register1 << 8) ^ value
|
||
}
|
||
}
|
||
|
||
if input_reflected != result_reflected {
|
||
register1 = reflect(register1, width)
|
||
}
|
||
return (register1 ^ final_xor_value) & significant_mask
|
||
}
|