BitString与python

BitString with python

我正在尝试使用python的位串来解释一个传入的数据包,并将其分解为可读的部分。数据包将包含一个头段(源(8bits)、目的地(8bits)、ns(3bits)、nr(3bits)、rsv(1bit)、lst(1bit)、opcode(8bits)、len(8bits)),有效负载介于0到128字节(由头中的len决定)和16位的CRC之间。

数据将通过COM端口以大数据包的形式到达。数据源于一个微控制器,它将数据打包并发送给用户,而这正是python的用武之地。

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

我刚接触过python,需要一些帮助才能让它脱离地面。

谢谢,埃里克

编辑

我目前有一段代码在运行,但它并没有产生我需要的东西……下面是我已经启动并运行的代码部分……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
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("
########Number of packets ="
+str(num_of_packets) +" ############

"
)

    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

"

                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

当震源和有效载荷均为1时,打印到终端的输出如下:

1
2
3
4
5
6
7
#######Number of packets = 1 #######

31
0x0a0101441310031
1
0
.... etc..

序列另一端的micro显示:0A0101441310031何时应读取1 1 44 1 31 0031

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

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

有什么想法吗????谢谢


您的确切问题有点含糊,但我应该能够帮助处理它的位字符串部分。

您可能已经将有效负载作为一个str进行了分析(如果您使用的是python 3,也可能是bytes,但不要担心——它的工作方式相同)。如果你还没到那么远,你就得问一个更基本的问题。我将组成一些要分析的数据(所有这些都是通过交互式Python会话完成的):

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

现在,您可以解压缩或使用位流上的reads来提取所需的内容。例如:

1
2
3
4
5
6
7
8
9
10
11
12
>>> 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'

这只是解析字节并将块解释为无符号整数、bools或字节。查看手册了解更多详细信息。

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

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

如果您希望它返回为python str,那么使用字节解释:

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

您也可以做一些更高级的事情,但是在Python中进行这项工作的一个好方法通常是打开一个交互式会话并尝试一些事情。