rts-sim-testing-service/example/balise_1023_830/main.go

407 lines
12 KiB
Go
Raw Normal View History

package main
import (
"fmt"
"log/slog"
"strconv"
"joylink.club/bj-rtsts-server/third_party/balise"
)
type Transponder struct {
// 应答器编号
Code int
// 应答器名称
Name string
// 应答器类型
Type string
// 校验码
CheckSum string
// 830报文
Msg830 string
// 1023报文
Msg1023 string
}
func main() {
transponderMap := ReadTransponders()
// v := transponderMap["FB121_BGZ"]
// b1023 := convertToBalise1023(v.Msg1023)
// replaced830 := replaceFirst10Bits(convertTo830(v.Msg830))
// scrambled830 := scrambling(replaced830, b1023.S)
// compare830(scrambled830, b1023.data830)
// count := 0
for _, v := range transponderMap {
// slog.Info("transponder", "name", v.Name, "code", v.Code, "checksum", v.CheckSum, "msg830", v.Msg830, "msg1023", v.Msg1023)
byte104, err := balise.DecodeByteString(v.Msg1023)
if err != nil {
slog.Error("解码应答器数据失败", "name", v.Name, "code", v.Code, "err", err)
continue
}
compare104Bytes(byte104, balise.ConvertByteStringToBytes(v.Msg830))
// b1023 := convertToBalise1023(v.Msg1023)
// source830 := convertTo830(v.Msg830)
// // replaced830 := replaceFirst10Bits(source830)
// // compare830(reverted830, source830)
// descrambled830 := descrambling(b1023.data830, b1023.S)
// reverted830 := revertFirst10Bits(descrambled830)
// // // scrambled830 := scrambling(replaced830, b1023.S)
// compare830(source830, reverted830)
// count++
// if count >= 10 {
// break
// }
}
}
// 比较830位数据
func compare104Bytes(bytes104 []byte, compare104 []byte) {
if len(bytes104) != 104 {
panic("invalid length")
}
for i := 0; i < 104; i++ {
fmt.Printf("%02x\n", bytes104[i])
fmt.Printf("%02x\n\n", compare104[i])
if bytes104[i] != compare104[i] {
slog.Info("error", "index", i, "bytes104", fmt.Sprintf("%02x", bytes104[i]), "compare", fmt.Sprintf("%02x", compare104[i]))
panic("104 bytes compare error")
}
}
}
type Balise1023 struct {
bits []byte // 1023报文,1023bit
data []byte // 数据位,913bit
data830 []byte // 830位数据
cb []byte // 控制位,3bit
sb []byte // 加扰位,12bit
S uint32 // 由加扰计算得到的S作为初始状态为S的32位线性反馈移位寄存器对数据进行加扰
esb []byte // 额外修正位,10bit
checkSum []byte // 校验位,85bit
}
func newBalise1023(bits []byte) *Balise1023 {
if len(bits) != 1023 {
panic("invalid length")
}
// for i := 0; i < 1023; i++ {
// if i%10 == 0 {
// println()
// }
// print(1022-i, ":", bits[i], ",")
// }
// println()
balise1023 := &Balise1023{
bits: bits,
}
balise1023.data = balise1023.getRange(1022, 110)
if len(balise1023.data) != 913 {
panic("invalid data length")
}
balise1023.data830 = convert913To830(balise1023.data)
balise1023.check11To10()
balise1023.cb = balise1023.getRange(109, 107)
for i, v := range balise1023.cb {
n := 109 - i
name := "b" + strconv.Itoa(109-i)
slog.Info("cb", name, v)
if n == 109 && v == 1 {
slog.Error("控制位cb错误cb109应该为0实际为1")
} else if n == 108 && v == 1 {
slog.Error("控制位cb错误cb108应该为0实际为1")
} else if n == 107 && v == 0 {
slog.Error("控制位cb错误cb107应该为1实际为0")
}
}
balise1023.sb = balise1023.getRange(106, 95)
balise1023.S = calculateS(balise1023.sb)
balise1023.esb = balise1023.getRange(94, 85)
balise1023.checkSum = balise1023.getRange(84, 0)
slog.Info("msg length", "datalen", len(balise1023.data), "cblen", len(balise1023.cb), "sblen", len(balise1023.sb), "esblen", len(balise1023.esb), "checkSumlen", len(balise1023.checkSum))
return balise1023
}
func (b *Balise1023) getRange(start, end int) []byte {
if start < 0 || end < 0 || start < end || start > 1022 {
panic("invalid range")
}
return b.bits[1022-start : 1022-(end-1)]
}
func (b *Balise1023) check11To10() {
b913 := b.data
compare := convert830To913(b.data830)
for i := 0; i < 913; i++ {
if b913[i] != compare[i] {
slog.Info("error", "idx", i, "b913", b913[i], "compare", compare[i])
panic("10 to 11 bit error")
}
}
}
// 转换字节字符串到bit数组左边为最高有效位MSB
func convertStringBytesToBits(msg string) []byte {
length := len(msg)
println("msg:", msg)
bytes := make([]byte, length/2)
for i := 0; i < length; i += 2 {
v, err := strconv.ParseUint(msg[i:i+2], 16, 8)
if err != nil {
panic(err)
}
bytes[i/2] = byte(v)
// slog.Info("i", "byteidx", i/2, "byte", fmt.Sprintf("%02x", v))
}
// 字节转换为bit数组
bits := make([]byte, length/2*8)
for i, bt := range bytes {
for j := 0; j < 8; j++ {
move := 7 - j
idx := i*8 + j
bits[idx] = (bt >> move) & 1
}
}
return bits
}
func convertTo830(msg string) []byte {
length := len(msg)
if length != 208 {
panic("invalid length")
}
// 字节转换为bit数组
bits := convertStringBytesToBits(msg)
bits830 := bits[0:830]
return bits830
}
func convertToBalise1023(msg string) *Balise1023 {
length := len(msg)
if length != 256 {
panic("invalid length")
}
// 字节转换为bit数组
bits := convertStringBytesToBits(msg)
bits1023 := bits[0:1023]
slog.Info("bits length", "len", len(bits1023))
return newBalise1023(bits1023)
}
// 将830位的二进制数组以10位为单位组成一个左边为最高有效位MSB的无符号整数数组除了第一个10位值其余值求和然后循环2的10次方次与其他值求和结果相加后模2的10次方若结果和第一个10位值相同则结束此值即为原始的第一个10位值将此值替换为第一个10位二进制数组依然是左边为MSB
func revertFirst10Bits(b []byte) []byte {
if len(b) != 830 {
panic("invalid length")
}
// 将830位的二进制数组以10位为单位组成一个左边为最高有效位MSB的无符号整数数组
bits := make([]uint16, 83)
for i := 0; i < 83; i++ {
bits[i] = uint16(balise.ToValLeftMsb(b[i*10 : i*10+10]))
// 打印输出
for j := 0; j < 10; j++ {
fmt.Printf("%01b", b[i*10+j])
}
print(" ")
if i != 0 && i%10 == 9 {
println()
}
}
println()
// 将除了第一个10位字整数求和
sum := uint64(0)
for i := 1; i < 83; i++ {
sum += uint64(bits[i])
}
// 循环2的10次方次与其他值求和结果相加后模2的10次方
for i := 0; i < 1024; i++ {
test := sum + uint64(i)
if test%1024 == uint64(bits[0]) {
bits[0] = uint16(i)
break
}
}
slog.Info("还原第一个10位值", "sum", sum, "bits[0]", bits[0], "bits[0]b", fmt.Sprintf("%010b", bits[0]))
rbits := make([]byte, 830)
// 将整个10位数组转换为二进制数组依然是MSB
u0bits := balise.ToBitsLeftMsb(int(bits[0]), 10)
for i := 0; i < 10; i++ {
rbits[i] = u0bits[i]
}
for i := 10; i < 830; i++ {
rbits[i] = b[i]
}
// compare830(b, rbits)
return rbits
}
// 将830位的二进制数组以10位为单位组成一个左边为最高有效位MSB的无符号整数数组然后求和后模2的10次方得到的结果覆盖第一个10位值然后将整个10位数组转换为二进制数组依然是左边为MSB
func replaceFirst10Bits(b []byte) []byte {
if len(b) != 830 {
panic("invalid length")
}
// 将830位的二进制数组以10位为单位组成一个左边为最高有效位MSB的无符号整数数组
bits := make([]uint16, 83)
for i := 0; i < 83; i++ {
bits[i] = uint16(balise.ToValLeftMsb(b[i*10 : i*10+10]))
// 打印输出
for j := 0; j < 10; j++ {
fmt.Printf("%01b", b[i*10+j])
}
print(" ")
if i != 0 && i%10 == 9 {
println()
}
}
println()
// 将每一个10位字整数求和后模2的10次方得到的结果覆盖第一个10位值
sum := uint64(0)
for i := 0; i < 83; i++ {
sum += uint64(bits[i])
// fmt.Printf("i=%d, v10=%d, v10b=%010b\n", i, bits[i], bits[i])
}
bits[0] = uint16(sum % 1024)
slog.Info("替换第一个10位值", "sum", sum, "bits[0]", bits[0], "bits[0]b", fmt.Sprintf("%010b", bits[0]))
rbits := make([]byte, 830)
// 将整个10位数组转换为二进制数组依然是MSB
u0bits := balise.ToBitsLeftMsb(int(bits[0]), 10)
for i := 0; i < 10; i++ {
rbits[i] = u0bits[i]
}
for i := 10; i < 830; i++ {
rbits[i] = b[i]
}
// compare830(b, rbits)
return rbits
}
// 由加扰位计算得到的S作为初始状态为S的32位线性反馈移位寄存器对数据进行加扰
func calculateS(sb []byte) uint32 {
// 由加扰计算得到的S作为初始状态为S的32位线性反馈移位寄存器对数据进行加扰
if len(sb) != 12 {
panic("invalid length")
}
B := balise.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
}
// 由加扰计算得到的S作为初始状态为S的32位线性反馈移位寄存器对数据进行加扰
// 1. 生成一个32位的线性反馈移位寄存器其初始状态为S左边为MSB
// 2. 系数h31,h30,h29,h27,h25和h0等于1(表示连接)所有其他系数都为0表示不连接
// 3. 然后电路被时钟驱动m-1次其中m是数据位的数量同时输入dn的每一位dn(m-1),dn(m-2),...,dn(0),便生成加扰后的码位在第一个时钟之前读取第一个输出out(m-1)
// 4. 生成的加扰码位是dn的每一位与S的最高位的异或值
// 5. 生成的加扰码位会根据系数进行异或反馈回S的最低位
// 几种可能性:
func scrambling(dn []byte, S uint32) []byte {
if len(dn) != 830 {
panic("invalid length")
}
// const Polynomial = 0x000000AF
out := make([]byte, len(dn))
t := S // 寄存器初始值
for i := 0; i < len(dn); i++ {
msb := (t >> 31) & 1
out[i] = (dn[i] ^ byte(msb)) & 1
// fmt.Printf("i=%d, t=%032b, msb=%d, dn=%d, out=%d\n", i, t, msb, dn[i], out[i])
xor := uint32(out[i])
t = (xor << 30) ^ (xor << 29) ^ (xor << 28) ^ (xor << 26) ^ (xor << 24) ^ t
t = (t << 1) | xor
}
return out
}
func descrambling(dn []byte, S uint32) []byte {
if len(dn) != 830 {
panic("invalid length")
}
// const Polynomial = 0x000000AF
out := make([]byte, len(dn))
t := S // 寄存器初始值
for i := 0; i < len(dn); i++ {
msb := (t >> 31) & 1
out[i] = (dn[i] ^ byte(msb)) & 1
// fmt.Printf("i=%d, t=%032b, msb=%d, dn=%d, out=%d\n", i, t, msb, dn[i], out[i])
xor := uint32(dn[i])
t = (xor << 30) ^ (xor << 29) ^ (xor << 28) ^ (xor << 26) ^ (xor << 24) ^ t
t = (t << 1) | xor
}
return out
}
// 将830位的二进制数组先以10位为一组分别转换为11位并组合
func convert830To913(b830 []byte) []byte {
if len(b830) != 830 {
panic("invalid length")
}
b913 := make([]byte, 913)
for i := 0; i < 83; i++ {
b11 := balise.To11(b830[i*10 : i*10+10])
for j := 0; j < 11; j++ {
b913[i*11+j] = b11[j]
}
}
return b913
}
func convert913To830(b913 []byte) []byte {
if len(b913) != 913 {
panic("invalid length")
}
b830 := make([]byte, 830)
for i := 0; i < 83; i++ {
b10, err := balise.From11(b913[i*11 : i*11+11])
if err != nil {
panic(err)
}
for j := 0; j < 10; j++ {
b830[i*10+j] = b10[j]
}
}
return b830
}
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")
}
}
}
// 以11位为一组比较两个913位的报文
func compare913(b913 []byte, b1023 *Balise1023) {
if len(b913) != 913 {
panic("invalid length")
}
compare := b1023.data
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()
}
}