2016-07-01 5 views
0

Ниже приведен мой код для приема данных через сокет.Как преобразовать комбинацию бинарных и ascii в читаемый человеком формат в python

from twisted.internet.protocol import Factory 
from twisted.protocols.basic import LineReceiver 
from twisted.internet import reactor 

class Chat(LineReceiver): 

    def lineReceived(self, line): 
     print(line) 

class ChatFactory(Factory): 

    def __init__(self): 
     self.users = {} # maps user names to Chat instances 

    def buildProtocol(self, addr): 
     return Chat() 

reactor.listenTCP(9600,ChatFactory()) 
reactor.run() 

Я получил ответ от клиента с

b'$$\x00pP$\x91\x97\x01\xff\xff\x99\x99P000002.000,V,0000.0000,N,00000.0000,E,0.00,000.00,060180,,*09|||0000|0000,0000|000000113|00000[\x86' 

который является комбинация шестнадцатеричного кода и ASCII, информация о местоположении в формате ASCII. Каков наилучший способ преобразования этих данных в человекообразный формат?

Мне нужно разобрать заголовок, L и ID.

<$$><L><ID><command><data><checksum><\r\n> 
  • заголовок = 2 байта, и это будет в шестнадцатеричном представлении кода 0x24
  • L = 2 байта, и это в формате шестнадцатеричного кода.
  • ID = 7 байт и в формате шестнадцатеричного кода.
  • команда = 2 байта, она будет в шестнадцатеричном коде
  • данные будут в формате ascii.
  • контрольная сумма = 2 байта и в шестнадцатеричном коде

Спасибо заранее.

+0

Расположение не кажется, ASCII - он содержит два '\ x99' байт в начало и заканчивается символом '\ x86'. Оба они выходят за пределы диапазона ASCII. Можете ли вы добавить к своему вопросу ожидаемый результат для данной входной строки? – mhawke

+0

Моего требуемый формат вывод будет '<$$><\r\n>' где $$ вне заголовка, L является длиной пакета и имеет 2bytes и в шестнадцатеричном коде, идентификатор из 7 байт, а в шестнадцатеричном коде, данные будут иметь максимум 100 байт и в коде ascii, контрольная сумма имеет 2 байта и в шестнадцатеричном коде. – dkakoti

ответ

1

Это может быть решен только с помощью двоичной строки:

import struct 
header = line[:2] 
if header!=b'$$': 
    raise RuntimeError('Wrong header') 
# Assumes you want two have 2 bytes, not one word 
L = struct.unpack('BB',line[2:4]) 
ID = struct.unpack('7B', line[4:11]) 
location = line[11:] 
print 'L={},{}, ID={}, location={}'.format(L[1],L[2], ''.join(str(b) for b in ID, location) 

Ссылка на структуры в другом ответе

+0

спасибо, что это работает. Просто хотелось узнать . в моем случае L - длина всего пакета, и это 2 байта и находится в шестнадцатеричном коде. Это будет struct.unpack ('2B', строка [2: 4))? и мне нужно преобразовать эти шестнадцатеричные коды в десятичные правые? Поправьте меня, если это неправильно! – dkakoti

+0

Это не Hexcode - это двоичные данные, которые представлены как \ x00, если символ ASCII для значения не имеет хорошего представления или отображается как символ (например, в случае $ для 0x24). Способ, которым я показал, равен байтам в виде десятичных чисел. Но я полагаю, что значение находится в размере слова (struct code 'h'), а затем вам действительно нужно обратиться к struct help Python - конец становится довольно уродливым с точки зрения конечности (как упоминал e-nouri). – oekopez

-1

Вы можете использовать struct.unpack(), но вам нужно знать, что вы собираетесь распаковывать (int, long, signed и т. Д.), Endiness, если он закодирован более чем на 1 байт, ASCII - 7 бит, закодированных на 1 байт.

Подробнее о структуре here.

+0

Может кто-то объясняет нижний план, пожалуйста, я хочу знать, что не так? –

Смежные вопросы