2024-08-08 13:23:25 +08:00
|
|
|
|
package balisecodec
|
2023-10-31 11:22:50 +08:00
|
|
|
|
|
2024-08-07 14:40:49 +08:00
|
|
|
|
import (
|
2024-08-08 13:23:25 +08:00
|
|
|
|
"encoding/hex"
|
2024-08-07 14:40:49 +08:00
|
|
|
|
"fmt"
|
|
|
|
|
"log/slog"
|
|
|
|
|
"strconv"
|
|
|
|
|
)
|
2023-10-31 11:22:50 +08:00
|
|
|
|
|
|
|
|
|
// 应答器数据编解码器
|
|
|
|
|
type Codec interface {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
Bytes1023 = 128
|
|
|
|
|
)
|
|
|
|
|
|
2024-08-07 14:40:49 +08:00
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-31 11:22:50 +08:00
|
|
|
|
// 解码应答器数据,1023/341位解码
|
2024-08-07 14:40:49 +08:00
|
|
|
|
// msg - 128字节数据
|
2023-10-31 11:22:50 +08:00
|
|
|
|
// return - 830/210位数据
|
2024-08-07 14:40:49 +08:00
|
|
|
|
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 {
|
2024-08-08 13:23:25 +08:00
|
|
|
|
bytes, err := hex.DecodeString(msg)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
2024-08-07 14:40:49 +08:00
|
|
|
|
}
|
|
|
|
|
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")
|
|
|
|
|
}
|
2023-10-31 11:22:50 +08:00
|
|
|
|
}
|
|
|
|
|
}
|