first commit

This commit is contained in:
lihansani
2026-07-13 15:37:05 +08:00
commit 8b11aa2efc
299 changed files with 206339 additions and 0 deletions

153
报文模拟解析/demo2.py Normal file
View File

@@ -0,0 +1,153 @@
import random
import struct
def generate_ais_message1():
"""生成AIS Message1位置报告 (M.1371-5 Annex8 3.1)"""
# 随机位置
lat, lon = 124, 30
# 转换为AIS格式
lat_ais = int((lat + 90) * 60000)
lon_ais = int((lon + 180) * 60000)
# 随机选择一艘船
mmsi = 200000000
COMM_STATES = [
{"sync_state": 0, "slot_timeout": 0, "sub_message": 0},
{"sync_state": 1, "slot_timeout": 1, "sub_message": 1},
{"sync_state": 2, "slot_timeout": 2, "sub_message": 2},
{"sync_state": 3, "slot_timeout": 3, "sub_message": 3}
]
# 随机通信状态
comm_state = random.choice(COMM_STATES)
comm_state_field = (
(comm_state["sync_state"] << 17) |
(comm_state["slot_timeout"] << 14) |
comm_state["sub_message"]
)
# 构建Message1 (168位/21字节)
msg = struct.pack('>I', (1 << 26) | (random.randint(0, 3) << 24) | (mmsi >> 6))
msg += struct.pack('>I', ((mmsi & 0x3F) << 26) | (random.randint(0, 15) << 22))
msg += struct.pack('>I', (random.randint(0, 255) << 24) | (random.randint(0, 1023) << 14))
msg += struct.pack('>I', (random.randint(0, 1) << 31) | (lon_ais & 0xFFFFFFF))
msg += struct.pack('>I', (lat_ais << 4) | (random.randint(0, 4095) >> 8))
msg += struct.pack('>I', ((random.randint(0, 4095) & 0xFF) << 24) | (random.randint(0, 3599) << 12))
msg += struct.pack('>I', (random.randint(0, 511) << 23) | (random.randint(0, 63) << 17) | (comm_state_field & 0x1FFFF))
return msg
gam = generate_ais_message1()
print(gam)
print(type(gam), len(gam))
def decode_ais_message1(data):
"""解码AIS Message1位置报告 (M.1371-5 Annex8 3.1)"""
# if len(data) != 21:
# raise ValueError("AIS消息1应为21字节")
# 将数据转换为整数列表
parts = [int.from_bytes(data[i:i+4], 'big') for i in range(0, 20, 4)]
parts.append(int.from_bytes(data[20:], 'big') << 24) # 最后一个字节
# 解码字段
decoded = {}
# 第一部分消息ID + 转发指示符 + MMSI高24位
decoded['message_id'] = (parts[0] >> 26) & 0x3F
decoded['repeat_indicator'] = (parts[0] >> 24) & 0x03
decoded['user_id'] = ((parts[0] & 0x00FFFFFF) << 6)
# 第二部分MMSI低6位 + 导航状态 + 旋转速率 + SOG高4位
decoded['user_id'] |= (parts[1] >> 26) & 0x3F
decoded['nav_status'] = (parts[1] >> 22) & 0x0F
rot_value = (parts[1] >> 14) & 0xFF
decoded['rot'] = rot_value if rot_value < 128 else rot_value - 256
decoded['sog'] = ((parts[1] & 0x00003F00) >> 8) << 6
# 第三部分SOG低6位 + 位置准确度 + 经度高21位
decoded['sog'] |= (parts[2] >> 26) & 0x3F
decoded['pos_acc'] = (parts[2] >> 25) & 0x01
decoded['longitude'] = ((parts[2] & 0x01FFFFFF) << 7)
# 第四部分经度低7位 + 纬度
decoded['longitude'] |= (parts[3] >> 25) & 0x7F
decoded['latitude'] = parts[3] & 0x07FFFFFF
# 第五部分COG + 实际航向 + 时戳高3位
decoded['cog'] = (parts[4] >> 20) & 0x0FFF
decoded['true_heading'] = (parts[4] >> 11) & 0x01FF
decoded['timestamp'] = ((parts[4] & 0x00000700) >> 8) << 3
# 第六部分时戳低3位 + RAIM标志 + 通信状态高10位
decoded['timestamp'] |= (parts[5] >> 29) & 0x07
decoded['raim'] = (parts[5] >> 24) & 0x01
decoded['comm_state'] = ((parts[5] & 0x00FFFFFF) >> 14) << 9
# 第七部分通信状态低9位
decoded['comm_state'] |= (parts[6] >> 23) & 0x1FF
# 添加spare字段协议中为保留位固定为0
decoded['spare'] = 0
return decoded
# 示例数据(从您的生成函数中获取)
data = b'\x06/\xaf\x08\x03@\x00\x00\x11\x93\x80\x00\x80\xc0B\xc0\x0c>\xc4\x00*\x8e\xa0\x00\xba\x02@\x01'
# 解码数据
decoded = decode_ais_message1(data)
# 打印解码结果
print("解码结果:")
for field, value in decoded.items():
print(f"{field}: {value}")
# # 生成AIS消息使用您的函数
# data = generate_ais_message1()
# print("生成的二进制数据:", data)
# # 解码数据
# decoded = decode_ais_message1(data)
# # 打印格式化结果
# print("\n解码结果:")
# print(f"消息ID: {decoded['message_id']}")
# print(f"转发指示符: {decoded['repeat_indicator']}")
# print(f"用户ID (MMSI): {decoded['user_id']}")
# # 导航状态描述
# nav_status_desc = {
# 0: "发动机使用中", 1: "锚泊", 2: "未操纵", 3: "有限适航性",
# 4: "受船舶吃水限制", 5: "系泊", 6: "搁浅", 7: "从事捕捞",
# 8: "航行中", 15: "未规定(默认)"
# }
# print(f"导航状态: {decoded['nav_status']} ({nav_status_desc.get(decoded['nav_status'], '未知状态')})")
# # 旋转速率描述
# rot = decoded['rot']
# if rot == -128:
# print("旋转速率: -128 (无可用旋转信息)")
# elif rot == 127:
# print("旋转速率: 127 (右旋超过5º/30s)")
# elif rot == -127:
# print("旋转速率: -127 (左旋超过5º/30s)")
# else:
# print(f"旋转速率: {rot}")
# # 位置准确度描述
# print(f"位置准确度: {decoded['pos_acc']} ({'高(>10m)' if decoded['pos_acc'] else '低(<10m)'})")
# # 转换为实际单位
# longitude_deg = decoded['longitude'] / (60 * 10000)
# latitude_deg = decoded['latitude'] / (60 * 10000)
# sog_knots = decoded['sog'] / 10.0
# cog_deg = decoded['cog'] / 10.0
# print(f"经度: {decoded['longitude']} (1/10,000 min) ≈ {longitude_deg:.5f}°")
# print(f"纬度: {decoded['latitude']} (1/10,000 min) ≈ {latitude_deg:.5f}°")
# print(f"地面航速: {decoded['sog']} (1/10节) ≈ {sog_knots:.1f}节")
# print(f"地面航线: {decoded['cog']} (1/10°) ≈ {cog_deg:.1f}°")
# print(f"实际航向: {decoded['true_heading']}°")
# print(f"时戳: {decoded['timestamp']}秒")
# print(f"RAIM标志: {decoded['raim']} ({'RAIM正在使用' if decoded['raim'] else 'RAIM未使用'})")
# print(f"通信状态: {decoded['comm_state']}")