CRC32 не е изчислен правилно

Използвам много прост алгоритъм за изчисляване на CRC32, но той дава грешни стойности.

Сравнявам изходните си стойности с тези на калкулатора, но винаги изглежда различно

unsigned int crc32_tab[256] = {
        0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
        0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
        0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
        0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
      .........,..............,.............,.........,...........
    };

Функцията, която използва справочната таблица, е

 unsigned int MyClass::crc32(unsigned int crc, const void *buf, unsigned int   size)
{
const unsigned int *p;

p = (const quint8 *)buf;
crc = crc ^~ 0xFFFFFFFF;

while(size--)
{
    crc = this->crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
}

return crc ^~ 0xFFFFFFFF;
}

Аз го наричам по този начин

 QString test= QString::number(mclass.crc32(0, crcval, 6))

person tulipe    schedule 05.07.2015    source източник
comment
Освен всички действителни проблеми, които вашият код може или не може да има, какво точно постига ^~ 0xFFFFFFFF?   -  person Iwillnotexist Idonotexist    schedule 05.07.2015
comment
Всъщност тази стъпка няма влияние, тъй като ако битът с нулева стойност ще остане 0, а ако е 1, също ще остане същият   -  person tulipe    schedule 05.07.2015
comment
Точно това беше моята гледна точка. Извършвате XOR с допълнение от всички единици, което е всички нули, което означава, че не правите нищо. Ако сте възнамерявали да допълвате битовете, трябва да използвате x = ~x;. Що се отнася до останалата част от вашия код, сигурни ли сте, че не изчислява битово обърнат резултат? Използване на правилния полином (CRC-32/Ethernet срещу CRC-32C/Castagnoli)?   -  person Iwillnotexist Idonotexist    schedule 05.07.2015
comment
Калкулаторът, който използвате, изглежда използва CRC-32 Ethernet генераторен полином.   -  person Iwillnotexist Idonotexist    schedule 05.07.2015
comment
Да, използвах го, но другият калкулатор използва ли друг CRC-32? Каква е разликата между тях?   -  person tulipe    schedule 05.07.2015
comment
Няма нито един CRC-32. Всъщност има цяло семейство CRC-32 алгоритми, всеки от които се различава по своя генериращ полином. Различен генераторен полином разбира се означава, че те произвеждат различни контролни суми за едни и същи данни и че тяхната реализация ще използва различни стойности на справочна таблица. Двата най-популярни алгоритъма CRC-32 вероятно са CRC-32 (Ethernet, генераторен полином 0x04C11DB7) и CRC-32C (Castagnoli, 0x1EDC6F41).   -  person Iwillnotexist Idonotexist    schedule 05.07.2015
comment
Използвам Ethernet и мисля, че калкулаторът, който използвах като референтен, го използва, така че. Прав ли съм?   -  person tulipe    schedule 05.07.2015
comment
Нека продължим тази дискусия в чата.   -  person tulipe    schedule 05.07.2015
comment
Защо това е маркирано qt?   -  person Hamish Moffatt    schedule 06.07.2015
comment
@HamishMoffatt Вероятно защото въпросният код се извиква от Qt C++ приложение. Въпреки това, като се има предвид, че проблемът се оказа, че няма нищо общо с Qt/не-Qt-ност на приложението, вероятно бих го премаркирал [c++] плюс всички други подходящи тагове.   -  person Iwillnotexist Idonotexist    schedule 06.07.2015


Отговори (1)


Решение, извлечено от дискусия в чата

Внедреният алгоритъм CRC-32 е CRC-32 Ethernet (генераторен полином 0x04C11DB7).

Този CRC-32 изисква:

  • Инициализира се с 0xFFFFFFFF.
  • И се финализира чрез XORing с 0xFFFFFFFF.

Следователно, трябва да премахнете изразите crc ^~ 0xFFFFFFFF във вашата функция, да предадете 0xFFFFFFFF при извикването на функцията и след като приключите с CRC обработката на данните, трябва да XOR върнатата стойност с 0xFFFFFFFF.

person Iwillnotexist Idonotexist    schedule 05.07.2015