CRC32 уже обработанных CRC32 данных с добавленными данными CRC

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

#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

У кого-нибудь есть идеи, почему он так себя ведет?


person mrhpogie    schedule 18.02.2015    source источник
comment
Посмотрите здесь: danielvik.com/2010/10/calculating-reverse-crc. .html , особенно в разделе реверсирования crc. Он демонстрирует, как получить ЛЮБУЮ желаемую CRC, добавив к данным четыре байта.   -  person Eugene Sh.    schedule 18.02.2015
comment
Спасибо большое. обязательно посмотрю повнимательнее   -  person mrhpogie    schedule 18.02.2015


Ответы (2)


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

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

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

person Mark Adler    schedule 19.02.2015

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

    crc = accumulatedCrc32 ^ 0xFFFFFFFF;

    return crc ^ 0xFFFFFFFF;

Поэтому при повторном создании crc для данных, содержащих исходные данные + crc, проверьте значение 0x2144DF1C. Если бы эти две строки были:

    crc = 0;

    return crc;

тогда вы получите нулевую контрольную сумму, если снова запустите контрольную сумму для данных + контрольная сумма.

person rcgldr    schedule 18.02.2015