Шестнадцатеричные данные из сокета, процесса и ответа
Вопрос
Разложим по частям.
У меня есть сокет, принимающий данные, и я получил их в \x31\x31\x31
формат.
Я знаю, что смогу получить то же число, разорвав \x
с чем-то вроде
for i in data: print hex(ord(i))
так что я получил 31
в каждом случае.
Но если я хочу добавить к данным 1 (так будет "32 32 32
"), чтобы отправить его в качестве ответа, как я могу его получить? \x32\x32\x32
снова?
Решение
«\x31» — это не формат, а текстовое представление двоичных данных.Как вы упомянули, ord() преобразует один байт двоичных данных в целое число, поэтому вы можете выполнять математические вычисления.
Чтобы преобразовать его обратно в двоичные данные в строке, вы можете использовать chr(), если он содержит только одно целое число.Если их много, вы можете использовать символ форматирования строки %c:
>>> "Return value: %c%c%c" % (5,6,7)
'Return value: \x05\x06\x07'
Однако, вероятно, лучший способ — использовать struct.
>>> import struct
>>> foo, bar, kaka = struct.unpack("BBB", '\x06\x06\x06')
>>> struct.pack("BBB", foo, bar+1, kaka+5)
'\x06\x07\x0b'
Возможно, вы даже захотите взглянуть на ctypes.
Другие советы
используйте модуль структуры
распакуйте и получите 3 значения в abc
(a, b, c) = struct.unpack(">BBB", your_string)
затем
a, b, c = a+1, b+1, c+1
и упаковать в ответ
response = struct.pack(">BBB", a, b, c)
более подробную информацию см. в модуле struct в документации Python.
Противоположностью ord() будет chr().
Итак, вы можете сделать это, чтобы добавить его:
newchar = chr(ord(i) + 1)
Чтобы использовать это в вашем примере:
newdata = ''
for i in data:
newdata += chr(ord(i) + 1)
print repr(newdata)
Но если вы действительно хотите работать с шестнадцатеричными строками, вы можете использовать encode() и decode():
>>> 'test string'.encode('hex')
'7465737420737472696e67'
>>> '7465737420737472696e67'.decode('hex')
'test string'
О боже, какой быстрый ответ!:D
Я думаю, что я застрял на параметре «>B» для структуры, поскольку я использовал «h» и параметры этого образца (новичок в struct.pack говорит!)
Попробовал кодировать/декодировать, но сокет на другой стороне принимает их как числа, а не в желаемом представлении "\x".
Мне очень нравится простота формата %c, и я буду использовать его как временную вещь (я не обрабатываю так много данных, поэтому у меня нет причин быть сверхэффективным :D) или как структуру, немного поигравшись с ней.
И в этом примере, чтобы просто играть с одним символом за раз, найдите рабочую структуру, используя только «>B», хе-хе.
Спасибо всем.