Как рассчитывается PNG CRC?

Последние 4 часа я изучал алгоритм CRC. Я почти уверен, что уже освоился.

Я пытаюсь написать png-кодировщик и не хочу использовать внешние библиотеки для вычисления CRC, а также для самой кодировки png.

Моя программа смогла получить те же CRC, что и примеры на уроках. Как и в Википедии : enter image description here

Используя тот же полином и сообщение, что и в примере, я смог получить один и тот же результат в обоих случаях. Я смог сделать это и для нескольких других примеров.

Однако я не могу правильно рассчитать CRC файлов png. Я проверил это, создав пустой, один пиксель большой .png файл в рисовании и используя его CRC для сравнения. Я скопировал данные (и имя чанка) из IDAT-фрагмента png (, из которого вычисляется CRC ), и вычислил его CRC, используя полином, представленный в спецификации png.

Полином, представленный в спецификации png , является следующим:

x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1

Который должен переводиться в:

1 00000100 11000001 00011101 10110111

Используя этот полином, я попытался получить CRC из следующих данных:

01001001 01000100 01000001 01010100
00011000 01010111 01100011 11101000
11101100 11101100 00000100 00000000
00000011 00111010 00000001 10011100

Вот что я получаю:

01011111 11000101 01100001 01101000 (MSB First)
10111011 00010011 00101010 11001100 (LSB First)

Это то, что является фактическим CRC:

11111010 00010110 10110110 11110111

I Я не совсем уверен, как это исправить, но я думаю, что я делаю эту часть из спецификации неправильно:

В PNG 32-битный CRC является инициализируется всеми 1, а затем данные из каждого байта обрабатываются от младшего значащего бита (1) до старшего значащего бита (128). После обработки всех байтов данных CRC инвертируется (берется его дополнение). Это значение передается (сохраняется в потоке данных) MSB первым. С целью разделения на байты и упорядочения младший значащий бит 32-битного CRC определяется как коэффициент члена x31.

Я не совсем уверен, что могу понять все это.

Кроме того, вот код, который я использую для получения CRC:

 public BitArray GetCRC(BitArray data)
    {
        // Prepare the divident; Append the proper amount of zeros to the end
        BitArray divident = new BitArray(data.Length + polynom.Length - 1);
        for (int i = 0; i < divident.Length; i++)
        {
            if (i < data.Length)
            {
                divident[i] = data[i];
            }
            else
            {
                divident[i] = false;
            }
        }

        // Calculate CRC
        for (int i = 0; i < divident.Length - polynom.Length + 1; i++)
        {
            if (divident[i] && polynom[0])
            {
                for (int j = 0; j < polynom.Length; j++)
                {
                    if ((divident[i + j] && polynom[j]) || (!divident[i + j] && !polynom[j]))
                    {
                        divident[i + j] = false;
                    }
                    else
                    {
                        divident[i + j] = true;
                    }
                }
            }
        }

        // Strip the CRC off the divident
        BitArray crc = new BitArray(polynom.Length - 1);
        for (int i = data.Length, j = 0; i < divident.Length; i++, j++)
        {
            crc[j] = divident[i];
        }
        return crc;
    }

Итак, как мне это исправить, чтобы соответствовать спецификации PNG?

10
задан MythicManiac 6 June 2014 в 13:03
поделиться