rts-sim-testing-service/third_party/message/rssp_code.go

244 lines
6.2 KiB
Go
Raw Normal View History

2023-10-30 14:32:49 +08:00
package message
//rssp 协议中crc校验查表法实现
// Crc16Table G(x)=X16+X11+X4+1计算初始值为0
var crc16Table []uint32 = nil
var crc32C1Table []uint32 = nil
var crc32C2Table []uint32 = nil
2023-11-02 14:37:50 +08:00
const ( //CRC生成多项式
2023-10-30 14:32:49 +08:00
RsspCrc16GX uint32 = 0b1_0000_1000_0001_0001 //生成多项式 G(X)=X16+X11+X4+1
RsspCrc32C1 uint32 = 0x100d4e63 //安全通道1 CRC32生成多项式
RsspCrc32C2 uint32 = 0x8ce56011 //安全通道1 CRC32生成多项式
)
2023-11-02 14:37:50 +08:00
const ( //时间戳生成多项式
RsspTsC1 uint32 = 0x0fc22f87
RsspTsC2 uint32 = 0xc3e887e1
)
2023-10-30 14:32:49 +08:00
2023-10-30 17:46:52 +08:00
// InitRsspCrcTable 初始化RSSP协议中需要的CRC表
func InitRsspCrcTable() {
2023-10-30 14:32:49 +08:00
if crc16Table == nil {
2023-10-30 17:46:52 +08:00
crc16Table = CreateCrcTable(RsspCrc16GX, 16, false)
2023-10-30 14:32:49 +08:00
}
if crc32C1Table == nil {
2023-10-30 17:46:52 +08:00
crc32C1Table = CreateCrcTable(RsspCrc32C1, 32, false)
2023-10-30 14:32:49 +08:00
}
if crc32C2Table == nil {
2023-10-30 17:46:52 +08:00
crc32C2Table = CreateCrcTable(RsspCrc32C2, 32, false)
2023-10-30 14:32:49 +08:00
}
}
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)
}
2023-10-30 17:46:52 +08:00
// CreateCrcTable 创建CRC表支持8、16、32位
func CreateCrcTable(polynomial uint32, width int, input_reflected bool) []uint32 {
var table = make([]uint32, 0, 256)
for bt := 0x00; bt <= 0xff; bt++ {
table = append(table, lookup(uint32(bt), polynomial, width, input_reflected))
}
return table
}
2023-10-30 14:32:49 +08:00
/////////////////////////////////////////////////////////////////////////////
// 反转(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
}
2023-10-30 17:46:52 +08:00
// 计算单个数值的crc
func lookup(data uint32,
2023-10-30 14:32:49 +08:00
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
}
2023-10-30 17:17:41 +08:00
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
2023-10-30 17:46:52 +08:00
value = lookup(shift_out^byteData, polynomial, width, input_reflected)
2023-10-30 17:17:41 +08:00
register1 = (register1 >> 8) ^ value
} else {
shift_out = (register1 >> (width - 8)) & register_lsb_mask
2023-10-30 17:46:52 +08:00
value = lookup(shift_out^byteData, polynomial, width, input_reflected)
2023-10-30 17:17:41 +08:00
register1 = (register1 << 8) ^ value
}
}
if input_reflected != result_reflected {
register1 = reflect(register1, width)
}
return (register1 ^ final_xor_value) & significant_mask
}
2023-11-02 14:37:50 +08:00
////////////////////////////////////////////////////////
// 线性反馈移位寄存器
type RsspLFSR struct {
polynomial uint32 //生成多项式
width int //寄存器宽度
register uint32 //寄存器
}
func NewRsspLFSR(polynomial uint32, width int, init_value uint32) *RsspLFSR {
var wd_msb_mask uint32 = 1 << (width - 1)
var wd_mask uint32 = 0xffffffff >> (32 - width)
polynomial &= wd_mask
polynomial = (polynomial >> 1) | wd_msb_mask
//
return &RsspLFSR{polynomial: polynomial, width: width, register: init_value}
}
func (r *RsspLFSR) move() {
var significant_mask uint32 = 0xffffffff >> (32 - r.width)
//
r.register &= significant_mask
cb := r.register & r.polynomial & significant_mask
out := bitXor(cb, r.width)
r.register >>= 1
r.register = r.register | (out << (r.width - 1))
r.register &= significant_mask
}
func (r *RsspLFSR) GetAndMove() uint32 {
rt := r.register
r.move()
return rt
}
// return 0 或 1
func bitXor(data uint32, width int) uint32 {
var v uint32 = 0
var lsb_mask uint32 = 1
for i := 0; i < width; i++ {
v ^= data >> i
}
return v & lsb_mask
}