Skip to main content
 首页 » 编程设计

python之带 python 的位串

2025年05月04日19mfryf

我正在尝试使用 bitstring for python 来解释传入的数据包并将其分解为可读的部分。数据包将包含一个 header (源(8 位)、目标(8 位)、NS(3 位)、NR(3 位)、RSV(1 位)、LST(1 位)、OPcode(8 位)、LEN(8 位)), 介于 0 和 128 字节之间的有效负载(由 header 中的 LEN 确定)和 16 位的 CRC。

数据将以大数据包的形式通过 com 端口到达。数据源自微 Controller ,微 Controller 将数据打包并将其发送给用户,这正是 python 发挥作用的地方。

因为我不确定在解析之前如何存储它,所以我没有任何代码。

我是 python 的新手,需要一些帮助才能开始。

谢谢, 埃里克

编辑

我目前有一段代码正在运行,但它并没有产生我所需要的......这是我已经启动并运行的代码部分......

def packet_make(ser): 
    src = 10 
    p = 0 
    lst = 0 
    payload_make = 0 
    crc = '0x0031' 
    ns = 0 
    nr = 0 
    rsv = 0 
    packet_timeout = 0 
 
    top = 256 
    topm = 255 
 
    #os.system(['clear','cls'][os.name == 'nt']) 
    print("\tBatts:   1 \t| Berry:   2 \t| Bessler: 3") 
    print("\tCordell: 4 \t| Dave:    5 \t| Gold:    6") 
    print("\tYen:     7   \t| Erik:    8 \t| Tommy:   9") 
    print("\tParsons: 10 \t| JP:     11 \t| Sucess: 12") 
    dst = raw_input("Please select a destination Adderss: ") 
 
    message = raw_input("Please type a message: ") 
 
 
 
    #################### Start Making packet################# 
    p_msg = message 
    message = message.encode("hex") 
    ln = (len(message)/2) 
    #print (ln) 
    ln_hex = (ln * 2) 
    message = list(message) 
    num_of_packets = ((ln/128) + 1) 
    #print (num_of_packets) 
 
    message = "".join(message) 
 
    src = hex(src) 
    dst = hex(int(dst)) 
    #print (message) 
 
    print("\n########Number of packets = "+str(num_of_packets) + " ############\n\n") 
 
    for p in range (num_of_packets): 
        Ack_rx = 0 
 
 
        if( (p + 1) == (num_of_packets)): 
            lst = 1 
        else: 
            lst = 0 
 
        header_info = 0b00000000 
 
        if ((p % 2) > 0): 
            ns = 1 
        else: 
            ns = 0   
 
 
        header_info = (header_info | (ns << 5))  
        header_info = (header_info | (nr << 2)) 
        header_info = (header_info | (rsv << 1)) 
        header_info = (header_info | (lst)) 
        header_info = hex(header_info) 
        #print (header_info) 
        op_code = '0x44' 
 
        if (lst == 1): 
            ln_packet = ((ln_hex - (p * 256)) % 256) 
            if (p > 0): 
                ln_packet = (ln_packet + 2) 
            else: 
                ln_packet = ln_packet 
            ln_packet = (ln_packet / 2) 
        #   print (ln_packet) 
        #   print() 
        else: 
            ln_packet = 128 
        #   print(ln_packet) 
        #   print() 
 
        #ll = (p * 128) 
        #print(ll) 
        #ul = ((ln - ll) % 128) 
        #print(ul) 
        #print (message[ll:ul]) 
 
        if ((p == 0)&(ln_hex > 256)): 
            ll = (p * 255) 
        #   print(ll) 
            payload_make = (message[ll:256]) 
        #   print (payload_make) 
        elif ((p > 0) & ((ln_hex - (p*256)) > 256)): 
            ll = (p * 256) 
        #   print(ll) 
            ll = (ll - 2) 
            ul = (ll + 256) 
        #   print (ul) 
 
            payload_make = (message[ll:ul]) 
        #   print(payload_make) 
        elif ((p > 0) & ((ln_hex - (p*256)) < 257)): 
            ll = (p * 256) 
        #   print(ll) 
            ll = (ll - 2) 
            ul = ((ln_hex - ll) % 256) 
 
            ul = (ll + (ul)) 
            ul = ul + 2 
            print() 
            print(ul) 
            print(ln_hex) 
            print(ln_packet) 
            print() 
        #   print(ul) 
            payload_make = (message[ll:ul]) 
        #   print(payload) 
        elif ((p == 0) & (ln_hex < 257)): 
            ll = (p * 255) 
            ul = ln_hex 
            payload_make = (message[ll:ul]) 
 
        print(payload_make) 
 
        packet_m = BitStream()   
########################HEADER######################### 
        packet_m.append('0x0') 
        packet_m.append(src)                        #src 
        packet_m.append('0x0')   
        packet_m.append(dst)                        #dst 
        if(int(header_info,16) < 16): 
            packet_m.append('0x0') 
        packet_m.append(header_info)                # Ns, Nr, RSV, Lst 
        packet_m.append(op_code)                    #op Code 
        #if(ln_packet < 16): 
            #packet_m.append('0x0') 
        packet_m.append((hex(ln_packet)))           #Length 
###################END OF HEADER#######################      
        packet_m.append(("0x"+payload_make))    #Payload 
        #packet_m.append(BitArray(p_msg))   #Payload 
        packet_m.append(crc)                    #CRC     
        #print() 
        #print(packet) 
        temp_ack = '0x00' 
        print(packet_m) 
        print(ln_packet) 
        while((Ack_rx == 0) & (packet_timeout <= 5)): 
            try:  
                ###### Send the packet 
                #ser.write(chr(0x31)) 
 
                str_pack = list(str(packet_m)[2:]) 
                "".join(str_pack) 
 
                ser.write(chr(0x02)) 
                #ser.write((str(packet_m)[2:])) 
                for i in range (len(str_pack)): 
                    t = ord(str_pack[i]) 
                    ser.write(chr(t)) 
                    print(chr(t)) 
 
 
                ser.write(chr(0x04)) 
                ser.write(chr(0x10)) 
 
                ack_packet = BitStream(ser.read()) 
                if((len(ack_packet) > 3)): 
                    temp_ack = ACK_parse(ack_packet) 
                else: 
                    packet_timeout = (packet_timeout + 1) 
                    print "why so serious\n\n" 
                if(temp_ack == '0x41'): 
                    Ack_rx = 1 
                elif (temp_ack == '0x4E'): 
                    Ack_rx = 0 
                else: 
                    Acl_rx = 0  
 
            except serial.SerialTimeoutException: #if timeout occurs increment counter and resend last packet 
                Ack_rx = 0 
                packet_timeout = (packet_timeout + 1) 
 
 
            except serial.SerialException: 
                print "Error ... is not Active!!!", port 

当source和payload都为1时,打印到终端的输出如下:

#######Number of packets = 1 ####### 
 
31 
0x0a0101441310031 
1 
0 
.... etc.. 

串口另一端的微 Controller 读取:0a0101441310031 什么时候应该读取 1 1 44 1 31 0031

Python 将每个值作为一个单独的字符发送,而不是将其作为一个字符。当它被附加到数据包中而不是存储到正确的长度和数据类型时,它似乎将十六进制分成 2 个 8 位位置而不是 1 个 8 位位置....

我从 Micro 读取的 python 代码部分在读取确认数据包时完美无缺。我没有用数据尝试过,但我认为这不会成为问题。 C 端无法从 python 端读取 ACK,因为它将十六进制值分成 2 个字符,而不是仅传输 8 位值....

有什么想法吗???谢谢

请您参考如下方法:

你的确切问题有点模糊,但我应该能够帮助解决它的位串部分。

您可能已经将有效负载分析为 str(或者可能是 bytes,如果您使用的是 Python 3,但不用担心 - 它的工作原理相同方式)。如果你还没有走那么远,那么你将不得不问一个更基本的问题。我将编造一些数据进行分析(所有这些都是通过交互式 Python session 完成的):

>>> from bitstring import BitStream 
>>> packet_data = '(2\x06D\x03\x124V\x03\xe8' 
>>> b = BitStream(bytes=packet_data) 

现在您可以解包或使用 BitStream 上的读取来提取您需要的东西。例如:

>>> b.read('uint:8') 
40 
>>> b.read('uint:8') 
50 
>>> b.readlist('uint:3, uint:3') 
[0, 1] 
>>> b.readlist('2*bool') 
[True, False] 
>>> b.readlist('2*uint:8') 
[68, 3] 
>>> b.read('bytes:3') 
'\x124V' 

这只是解析字节并将 block 解释为无符号整数、 bool 值或字节。查看 the manual 了解更多详情。

如果你只是想要有效载荷,那么你可以只提取长度然后通过切片来获取它:

>>> length = b[32:40].uint 
>>> b[40:40 + length*8] 
BitStream('0x123456') 

如果你想把它作为 Python str 返回,那么使用字节解释:

>>> b[40:40 + 3*8].bytes 
'\x124V' 

您还可以执行更多高级操作,但开始使用 Python 的一个好方法通常是打开一个交互式 session 并尝试一些操作。