rts-sim-testing-service/third_party/message/rssp_crc.go
2023-10-30 17:17:41 +08:00

229 lines
5.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)&register_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
}