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 }