2015-02-25 4 views
0

Большинство реализованных CRC было , добавив вычисленное значение CRC для сообщения (полезной нагрузки) и проверку нулевого результата в приемнике после всех байтов, включая. Значение CRC было подано через регистр CRC. Очевидно, что это вполне стандартный подход.Вычисление начального значения CRC вместо добавления CRC к полезной нагрузке

Теперь я хотел бы использовать другой подход:

  1. Вычислить значение от полезной нагрузки.
  2. Используйте это значение в качестве начального значения для CRC регистра перед тем сообщений (байты полезной нагрузки) подается через ЦИК зарегистрировать таким образом, что после того, как результат последнего байта полезной нагрузки подавались через будет равен нулем.

Каков наилучший подход для этого? Есть ли у вас хорошая идея или какие-то указатели, где копать глубже?

ps: Почему я хочу это сделать? В некоторых приложениях (ПЗУ) я не могу добавлять данные, поскольку данные хранятся в конце адресного пространства ПЗУ. Поэтому я хотел бы либо предварительно загрузить регистр CRC, либо добавить значение к сообщению.

ответ

2

Теперь я запрограммировал решение для вышеупомянутой проблемы, которое было проще, чем я изначально думал, что это будет.

Я нашел несколько статей о том, как можно подделать CRC. Это означает, как исправлять данные таким образом, чтобы рассчитанное значение CRC имело предопределенное значение .

Используя такой подход, мне просто пришлось использовать последние байты моей фактической полезной нагрузки как значение CRC, что совершенно очевидно.

Наконец, мне нужно было вычислить «обратный» CRC, используя мои данные полезной нагрузки. Результатом этого расчета является начальное значение, которое я должен использовать, когда вычисляет CRC.

Как я работает на очень ограниченной памяти системы я уменьшил размер таблица КПР с 256 записей (1024 байт для CRC32) вниз до 16 записей (64 байта), и теперь обрабатывать каждый байт в два этапа теперь, когда все еще намного быстрее, чем смещение бит.

// Reverse CRC table for Castagnoli polynomial (0x1EDC6F41) 
static const unsigned long crc32c_revTable[16] = 
{ 
    0x00000000L, 0x05EC76F1L, 0x0BD8EDE2L, 0x0E349B13L, 
    0x17B1DBC4L, 0x125DAD35L, 0x1C693626L, 0x198540D7L, 
    0x2F63B788L, 0x2A8FC179L, 0x24BB5A6AL, 0x21572C9BL, 
    0x38D26C4CL, 0x3D3E1ABDL, 0x330A81AEL, 0x36E6F75FL 
}; 

unsigned long calcReverseCRC32C(unsigned long crc32c, 
           const unsigned char* pData, 
           unsigned long len) 
{ 
    while (len--) 
    { 
     crc32c = (crc32c << 4)^crc32c_revTable[crc32c >> 28]; 
     crc32c = (crc32c << 4)^crc32c_revTable[crc32c >> 28]; 
     crc32c ^= *pData--; 
    } 

    return crc32c; 
} 

Использование:

{ 
    // This array contains test data with 4 bytes CRC appended 
    // The result of CRC-32C calculation using this data is zero 
    unsigned char arr[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', 
          0x7c, 0x6d, 0xf9, 0x1c}; 

    unsigned long expectedResultOfCRC = 0; 
    unsigned long init = calcReverseCRC32C(expectedResultOfCRC, 
              &arr[sizeof(arr) -1], 
              sizeof(arr)); 
}