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

407 lines
12 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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()
}
}