Я пытаюсь декодировать поток Novatel GPS в Python, и у меня есть все компоненты для сортировки по синхронизации, заголовку и полезной нагрузке, но я не могу реплицировать CRC32, используемый как часть сообщений. Алгоритм, используемый для генерации CRC добавляется на сообщении записывается в с следующим образом:Воспроизведение алгоритма C CRC32 в Python с crcmod
#include <iostream>
#include <string>
using namespace std;
#define CRC32_POLYNOMIAL 0xEDB88320L
//#define CRC32_POLYNOMIAL 0x04C11DB7L
unsigned long CRC32Value(int i)
{
int j;
unsigned long ulCRC;
ulCRC = i;
for (j = 8; j > 0; j--)
{
if (ulCRC & 1)
ulCRC = (ulCRC >> 1)^CRC32_POLYNOMIAL;
else
ulCRC >>= 1;
}
return ulCRC;
}
unsigned long CalculateBlockCRC32(
unsigned long ulCount,
unsigned char *ucBuffer)
{
unsigned long ulTemp1;
unsigned long ulTemp2;
unsigned long ulCRC = 0;
while (ulCount-- != 0)
{
ulTemp1 = (ulCRC >> 8) & 0x00FFFFFFL;
ulTemp2 = CRC32Value(((int)ulCRC^*ucBuffer++) & 0xff);
ulCRC = ulTemp1^ulTemp2;
}
return(ulCRC);
}
int main()
{
unsigned char buffer[] = {0xaa, 0x44, 0x12, 0x1c, 0x2a, 0x00, 0x02, 0x20, 0x48, 0x00, 0x00, 0x00, 0x90, 0xb4, 0x93, 0x05, 0xb0, 0xab, 0xb9, 0x12, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xbc, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1b, 0x04, 0x50, 0xb3, 0xf2, 0x8e, 0x49, 0x40, 0x16, 0xfa, 0x6b, 0xbe, 0x7c, 0x82, 0x5c, 0xc0, 0x00, 0x60, 0x76, 0x9f, 0x44, 0x9f, 0x90, 0x40, 0xa6, 0x2a, 0x82, 0xc1, 0x3d, 0x00, 0x00, 0x00, 0x12, 0x5a, 0xcb, 0x3f, 0xcd, 0x9e, 0x98, 0x3f, 0xdb, 0x66, 0x40, 0x40, 0x00, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03};
unsigned long crc = CalculateBlockCRC32(sizeof(buffer), buffer);
cout << hex << crc << endl;
}
Результатом этого является 0x42, 0xdc, 0x4c, 0x48 - что соответствует примеру, приведенному в руководстве, так что это хороший старт.
Хотя я мог бы использовать этот алгоритм в коде, который я пишу, я предпочел бы оставаться на Python там, где это возможно, поэтому на данный момент я чувствую, что у меня есть два варианта. Я могу либо перевести это на сам Python, либо надеяться, что есть встроенная функция или модуль Python, способный сделать это для меня, что я и делал. До сих пор я нашел три функции/модули:
- binascii.crc32
- zlib.crc32
- модуль crcmod
Из них два сверху дают тот же неправильный результат, и я не могу сказать любой способ изменения настроек или указания аргументов, которые могут повлиять на это положительно.
crcmod, с другой стороны, имеет множество настроек и предопределенных функций, которые, я думаю, должны быть способны делать то, что я ищу. Формат для создания функции CRC заключается в следующем:
crcmod.mkCrcFun(poly[, initCrc, rev, xorOut])
Из из важных вещей, которые я нашел там предопределенные функции CRC, а версия CRC32 это соответствует результатам binascii и Zlib:
Name Polynomial Reversed? Init-value XOR-out Check
crc-32 0x104C11DB7 True 0x00000000 0xFFFFFFFF 0xCBF43926
Так, по крайней мере, это помогает мне понять, откуда берутся варианты zlib и binascii в терминах используемого полинома.
Я убежден, что поэтому я должен иметь возможность генерировать тот же результат, что и алгоритм C, используя эту функцию, но не будучи хорошо разбирающимся в C. Я не уверен, как это сделать. Полином, используемый в алгоритме C, представляет собой обратное представление многочлена, поэтому это означает, что приведенные выше настройки должны работать, но они не генерируют ответ выше в соответствии с кодом C.
Что я ищу для определения этих параметров, есть ли модуль/функция, которая будет делать это, чего я не видел, или это не сработает, и вместо этого я должен просто начать перевод этого C в Python ?
Просто, чтобы подтвердить, что это работает с Python 2 и 3 сейчас. Благодарю. – Folau