2015-02-18 2 views
3

Я использую следующий C Algo для вычисления CRC32 по данным:CRC32 уже CRC32 обработанных данных с данными CRC добавляется

#define CRC32_POLYNOM_REVERSED 0xEDB88320 

uint32 calcCrc32(uint8* buffer, uint32 bufferSize) { 
    return accumulateCrc32(0, buffer, bufferSize); 
} 

uint32 accumulateCrc32(uint32 accumulatedCrc32, uint8* buffer, uint32 bufferSize) { 
    uint32 i, j; 
    uint32 crc, mask; 

    crc = accumulatedCrc32^0xFFFFFFFF; 

    for (i = 0; i < bufferSize; i++) { 
     crc ^= buffer[i]; 
     for (j = 8; j > 0; j--) { 
      mask = -(crc & 1); 
      crc = (crc >> 1)^(CRC32_POLYNOM_REVERSED & mask); 
     } 
    } 

    return crc^0xFFFFFFFF; 
} 

Когда я применить его к любым данным и сцепить получившиеся 4 байта CRC32 к данные и запустить его через эту рутину снова, это всегда заканчивается с результатом

crc32 = 0x2144DF1C

Anybody имея представление о том, почему он ведет себя, как это?

+0

Посмотрите здесь: http://www.danielvik.com/2010/10/calculating-reverse-crc.html, в частности, в разделе «Обращение crc». Он демонстрирует, как получить ЛЮБЫЙ желаемый CRC, добавив четыре байта в данные. –

+0

thx очень много. Я обязательно присмотрюсь ближе – mrhpogie

ответ

3

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

В математике CRC вы можете рассмотреть операцию деления, где дивиденд является сообщением, делителем является полином CRC, а остальной частью деления является CRC. Если вы добавите CRC в сообщение, это будет эффективно вычитать остаток. Затем, когда вы делите , сообщение от полинома, вы получите нулевой остаток. В области целых чисел 137% 7 == 4. Я вычитаю 4 из 137, я получаю 133. Тогда 133% 7 == 0.

В этом случае есть предварительная и пост-обработка (^ 0xFFFFFFFF с) , Тогда результат не равен нулю, а другой константе. Эта константа - это просто CRC сообщения «00 00 00 00».

+0

Это бьет пятно – mrhpogie

1

Он всегда должен в конечном итоге с crc32 = 0x2144DF1C из этих двух линий:

crc = accumulatedCrc32^0xFFFFFFFF; 

    return crc^0xFFFFFFFF; 

Так что, когда снова регенерации CRC данных, которая содержит исходные данные + CRC, проверьте значение 0x2144DF1C. Если эти две линии были:

crc = 0; 

    return crc; 

тогда вы получите ЦПК нуля, если вы снова запускали на данных CRC + стс.

 Смежные вопросы

  • Нет связанных вопросов^_^