rts-sim-testing-service/third_party/balisecodec/codec.go

179 lines
4.3 KiB
Go
Raw Normal View History

package balisecodec
import (
"encoding/hex"
"fmt"
"log/slog"
"strconv"
)
// 应答器数据编解码器
type Codec interface {
}
const (
Bytes1023 = 128
)
func Decode(byte128 []byte) ([]byte, error) {
if len(byte128) != Bytes1023 {
return nil, buildError("应答器报文长度错误, 期望长度为128字节")
}
bits1023 := convertTo1023Bits(byte128)
// 检查控制位
err := checkCb(bits1023)
if err != nil {
return nil, err
}
// 检查913位数据并将913位数据转换为830位数据
data913 := getRange(bits1023, 1022, 110)
scrambled830, err := convert913To830(data913)
if err != nil {
return nil, err
}
// 根据加扰位计算得到加扰器初始值S
S := calculateS(getRange(bits1023, 106, 95))
// 解扰
descrambled830 := descrambling(scrambled830, S)
// 还原第一个10位值
reverted830 := revertFirst10Bits(descrambled830)
// 转换为左边为最高有效位MSB的字节数组
byte104 := toBytes(reverted830)
return byte104, nil
}
// 解码应答器数据,1023/341位解码
// msg - 128字节数据
// return - 830/210位数据
func DecodeByteString(msg string) ([]byte, error) {
length := len(msg)
if length != 256 {
panic("invalid length")
}
// 字节转换为字节数组
slog.Debug("待解码的1023应答器报文", "msg", msg)
bytes := ConvertByteStringToBytes(msg)
return Decode(bytes)
}
// 转换字节16进制字符串为字节数组
func ConvertByteStringToBytes(msg string) []byte {
bytes, err := hex.DecodeString(msg)
if err != nil {
panic(err)
}
return bytes
}
// 将830位补末尾补1到832位然后转换为左边为最高有效位MSB的字节数组
func toBytes(reverted830 []byte) []byte {
reverted830 = append(reverted830, 1, 1)
byte104 := make([]byte, 104)
for i := 0; i < 104; i++ {
byte104[i] = byte(ToValLeftMsb(reverted830[i*8 : i*8+8]))
}
return byte104
}
func buildError(msg string) error {
return fmt.Errorf("应答器1023解码错误%s", msg)
}
// 检查控制位
func checkCb(bits1023 []byte) error {
cb := getRange(bits1023, 109, 107)
for i, v := range cb {
n := 109 - i
name := "b" + strconv.Itoa(109-i)
slog.Info("cb", name, v)
if n == 109 && v == 1 {
return buildError("控制位cb错误b109应该为0实际为1")
} else if n == 108 && v == 1 {
return buildError("控制位cb错误b108应该为0实际为1")
} else if n == 107 && v == 0 {
return buildError("控制位cb错误b107应该为1实际为0")
}
}
return nil
}
func getRange(bits []byte, start, end int) []byte {
if start < 0 || end < 0 || start < end || start > 1022 {
panic("invalid range")
}
return bits[1022-start : 1022-(end-1)]
}
// 转换128字节数据为1023位数据
func convertTo1023Bits(byte128 []byte) []byte {
if len(byte128) != 128 {
panic("invalid length")
}
// 字节转换为bit数组
bits := make([]byte, 1024)
for i, bt := range byte128 {
for j := 0; j < 8; j++ {
move := 7 - j
idx := i*8 + j
bits[idx] = (bt >> move) & 1
}
}
bits1023 := bits[0:1023]
return bits1023
}
// 由加扰位计算得到的S作为初始状态为S的32位线性反馈移位寄存器对数据进行加扰
func calculateS(sb []byte) uint32 {
// 由加扰计算得到的S作为初始状态为S的32位线性反馈移位寄存器对数据进行加扰
if len(sb) != 12 {
panic("invalid length")
}
B := ToValLeftMsb(sb)
const A uint64 = 2801775573
S := uint32((A * uint64(B)) % (1 << 32))
slog.Info("由12位加扰位计算得到整数S", "B", B, "S", S, "Sb", fmt.Sprintf("%032b", S))
return S
}
// 以11位为一组比较两个913位的报文
func compare913(b913 []byte, compare []byte) {
if len(b913) != 913 {
panic("invalid length")
}
for i := 0; i < 913; i += 11 {
for j := 0; j < 11; j++ {
print(b913[i+j])
}
println()
for j := 0; j < 11; j++ {
print(compare[i+j])
}
println()
println()
}
}
// 比较830位数据
func compare830(b830 []byte, compare830 []byte) {
if len(b830) != 830 {
panic("invalid length")
}
for i := 0; i < 83; i++ {
for j := 0; j < 10; j++ {
fmt.Printf("%01b", b830[i*10+j])
}
println()
for j := 0; j < 10; j++ {
fmt.Printf("%01b", compare830[i*10+j])
}
println()
println()
}
for i := 0; i < 830; i++ {
if b830[i] != compare830[i] {
slog.Info("error", "index", i, "b830", b830[i], "compare", compare830[i])
panic("830 bit compare error")
}
}
}