基於JT808協議的自動化測試----解析二進制數據


思路: 本文運用python3中的bitstring庫來解析二進制數據

一. 按bit位來解析二進制數據

1.1 協議說明

 

1.2 解析代碼

# -*- coding: utf-8 -*-
# @Time    : 2021/4/22 17:15
# @Author  : chinablue
# @File    : tmp0422.py

import bitstring

# 十六進制數據消息(大端模式)
recv_data = "30CFD6D4DAB2E2CAD4545453D3EFD2F4B2A5B1A8"

# 解析消息
bs = bitstring.BitStream(hex=recv_data)
fmt_head = """ pad:2,
               bin:1=infoType,
               bin:1=isAdShow,
               bin:1=isTTS,
               bin:1=isDisplayShow,
               pad:1,
               bin:1=isEmergency,
           """
res_list = bs.readlist(fmt_head)
context = bitstring.BitStream(hex=bs.hex[2:]).tobytes().decode("gbk")

# 保存消息
res_dict = {}
res_dict.setdefault("infoType", res_list[0])
res_dict.setdefault("isAdShow", int(res_list[1], base=16))
res_dict.setdefault("isTTS", int(res_list[2], base=16))
res_dict.setdefault("isDisplayShow", res_list[3])
res_dict.setdefault("isEmergency", res_list[4])
res_dict.setdefault("context", context)

print(res_dict)

1.3 注意事項

  • fmt_head中, pad:2 表示讀取2個bit, 不返回數據; bin:1=infoType 表示讀取1個bit,返回二進制數據, 別名為infoType
  • bitstring.BitStream(hex=bs.hex[2:]).tobytes().decode("gbk") 表示獲取到除了第一個字節的所有字節, 並GBK編碼

二. 按固定字節來解析二進制數據

2.1 協議說明

 

 

2.2 解析代碼

# -*- coding: utf-8 -*-
# @Time    : 2021/4/22 17:15
# @Author  : chinablue
# @File    : tmp0422.py

import bitstring

# 十六進制數據消息
recv_data = "020016000B0102057D404080"

# 解析消息
bs = bitstring.BitStream(hex=recv_data)
fmt_head = """ hex:8=channelId,
    hex:16=shootCmd,
    hex:16=time,
    hex:8=saveFlag,
    hex:8=dpi,
    hex:8=quality,
    hex:8=luminance,
    hex:8=contrast,
    hex:8=saturation,
    hex:8=chroma,
"""
res_list = bs.readlist(fmt_head)

# 保存消息
res_dict = {}
res_dict.setdefault("channelId", res_list[0])
res_dict.setdefault("shootCmd", int(res_list[1], base=16))
res_dict.setdefault("time", int(res_list[2], base=16))
res_dict.setdefault("saveFlag", res_list[3])
res_dict.setdefault("dpi", res_list[4])
res_dict.setdefault("quality", int(res_list[5], base=16))
res_dict.setdefault("luminance", int(res_list[6], base=16))
res_dict.setdefault("contrast", int(res_list[7], base=16))
res_dict.setdefault("saturation", int(res_list[8], base=16))
res_dict.setdefault("chroma", int(res_list[9], base=16))

print(res_dict)

2.3 注意事項

  • fmt_head中, hex:8=channelId 表示讀取1個字節(8個bit), 並返回字節對應的十六進制, 別名為channelId 

三. 動態讀取解析二進制數據

3.1 協議說明

 

3.2 解析代碼

# -*- coding: utf-8 -*-
# @Time    : 2021/4/22 17:15
# @Author  : chinablue
# @File    : tmp0422.py

import bitstring

# 十六進制數據消息
recv_data = "0200000002040000000C00000013093132372E302E302E31"

# 解析消息
bs = bitstring.BitStream(hex=recv_data)
fmt_head1 = """
       hex:8=count,
    """
res_list = bs.readlist(fmt_head1)
count = int(res_list[0], base=16)

res_dict = {}
res_dict.setdefault("count", count)

tmp_list = []
res_dict.setdefault("list", tmp_list)

for _ in range(count):
    tmp_dict = {}

    fmt_head2 = """
           hex:32=id_hex,
           hex:8=valueLen_hex,
       """
    res_list = bs.readlist(fmt_head2)

    id_hex = res_list[0]
    valueLen_hex = res_list[1]
    valueLen = int(valueLen_hex, base=16)

    tmp_dict.setdefault("id_hex", id_hex)
    tmp_dict.setdefault("valueLen_hex", valueLen_hex)
    tmp_dict.setdefault("valueLen", valueLen)

    fmt_head3 = """ hex:valueLen_hex=value_hex,
       """
    res_list = bs.readlist(fmt_head3, valueLen_hex=valueLen * 8)
    value_hex = res_list[0]

    # 按整數或字符串解析
    if id_hex in ["00000013", "00000017"]:
        value = bitstring.BitStream(hex=value_hex).tobytes().decode("gbk")
    else:
        value = int(value_hex, base=16)

    tmp_dict.setdefault("value_hex", value_hex)
    tmp_dict.setdefault("value", value)

    tmp_list.append(tmp_dict)

print(res_dict)

3.3 注意事項

  • 通過fmt_head1來獲取字段[參數總數], 通過fmt_head2來獲取每個參數的字段[參數id]和字段[參數長度], 通過fmt_head3來獲取每個參數的字段[參數值](需要通過參數長度來獲取)
  • fmt_head3中hex:valueLen_hex=value_hex 表示讀取valueLen_hex個bit, 並返回字節對應的十六進制, 別名為value_hex
  • 動態讀取數據時, 需要在readlist方法中填寫對應的動態參數. 如: bs.readlist(fmt_head3, valueLen_hex=valueLen * 8)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM