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位值……
有什么想法吗????谢谢
您的确切问题有点含糊,但我应该能够帮助处理它的位字符串部分。
您可能已经将有效负载作为一个
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中进行这项工作的一个好方法通常是打开一个交互式会话并尝试一些事情。