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
Другие вопросы по тегам