Python конвертировать сеть байтов
Я пытаюсь реализовать проверку CRC по сетевому протоколу. Расчет CRC выполняется через библиотеку PyCRC.
PyCRC сгенерирует контрольную сумму для данного пакета и выдаст такой результат: CB3D9FD1
Когда я пытаюсь отправить его по проводам, каким-то образом python модифицирует мою строку и преобразует ее в ascii в Hex, например:
Crc = "CB3D9FD1"
...
buffer = "\x41\x42\x43\x44"+crc
...
s.send(buffer)
На проводе я увижу что:
\x41\x42\x43\x44***\x43\x42\x33\x44\x39\x46\x44\x31***
Вместо:
\x41\x42\x43\x44***\xCB\x3D\x9F\xD1***
Любые способы решить эту проблему легко?
Спасибо!
3 ответа
На самом деле, не конвертируйте свой CRC в ASCII. Сохраните его в шестнадцатеричном виде, а затем упакуйте в байтовую строку, используя struct.pack::
buffer += struct.pack("L", crc)
Если вы преобразовали CRC в строку, содержащую "CB3D9FD1", то правильная последовательность байтов будет 0x43 0x42 0x33 0x44 0x39 0x46 0x44 0x31. Не преобразовывайте крик в строку и не анализируйте строку как шестнадцатеричное (по два символа на каждый байт).
Назначая это так: crc = "CB3D9FD1"
вы говорите, что сделать var crc 8-байтовой строкой. Как говорит @Bashwork, вам нужно преобразовать его из шестнадцатеричной строки в числовую или оставить ее числовой. Присвойте ему значение 0x, чтобы получить числовое значение: crc=0xCB3D9FD1
,
pack("L",x) означает, что я даю вам x, которое является (должно быть) целым числом, и я хочу, чтобы вы упаковали его как длинную без знака.
Вы получаете "struct.error: не может преобразовать аргумент в целое число", потому что вы передаете пакет ("L",...) строку "CB3D9FD1".
RTFM, что означают "L", "I" и другие аргументы: https://docs.python.org/2/library/struct.html
Упакуйте CRC, так как работает длинное целое число: и вы получаете 0 с дополнением до 64 бит (на моем ПК. YMMV)
>>> from struct import pack
>>> crc=0xcb3d9fd1
>>> repr(crc)
'3409813457'
>>> pack("L", crc)
'\xd1\x9f=\xcb\x00\x00\x00\x00'
>>> print crc
3409813457
Может быть, вы хотите использовать пакет ("Я",...): чтобы получить 32 бита
>>> pack("I",crc)
'\xd1\x9f=\xcb'
Сбой, если попытаться упаковать строку CRC с пакетом ("L",...):
>>> crc = "CB3D9FD1"
>>> repr(crc)
"'CB3D9FD1'"
>>> pack("L", crc)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: cannot convert argument to integer