407 lines
12 KiB
Go
407 lines
12 KiB
Go
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()
|
||
}
|
||
}
|