Как вычислить Adler32 в zlib

Что касается контрольной суммы, adler32, используемой в zlib.

Из рфк 1950:

ADLER32: содержит значение контрольной суммы несжатых данных (за исключением любых данных словаря), вычисленных в соответствии с алгоритмом Adler-32.

Вот png (zlib в IDAT). введите здесь описание изображения

  • синий = длина, 4 байта
  • красный = тип, 4 байта
  • желтый = crc, 4 байта
  • зеленый = заголовок zlib, 2 байта
  • серый = данные zlib, разные байты
  • розовый = adler32, 4 байта

Теперь анализ серых данных и передача данных zlib внешней программе, которая вычисляет adler32.

введите здесь описание изображения

Результат 64c60bbd, а не b0337596.


...или при передаче данных из карты изображений.

введите здесь описание изображения

Результат 1a49bac4, а не b0337596


Код контрольной суммы.exe:

const uint32_t MOD_ADLER = 65521;  
uint32_t adler32(unsigned char *data, size_t len) {
  uint32_t a = 1, b = 0;
  size_t index;  
  for (index = 0; index < len; ++index) {
    a = (a + data[index]) % MOD_ADLER;
    b = (b + a) % MOD_ADLER;
  }
  return (b << 16) | a;
}

int main(int argc, const char* argv[]) {
  if(argc == 2) {
    ifstream ifs(argv[1]);
    char c;
    unsigned char data[50000];
    int len = 0;

    while( ifs.get(c) )
      data[len++] = c;

    if( len >= 50000 )
      cout<<"Error: array overflow.\n";

    uint32_t result = adler32(data, len);
    cout<< "\n" << std::hex << result << "\n" ;
    return 0;
  }
}

Вопрос, что могло вызвать расхождение в расчетах? то есть какие именно входные данные для zlib's adler32?

Решение:

Как сказано, zlib adler32 вычисляется по несжатому потоку данных, который в формате png представляет собой поток данных после фильтрации. В данном случае это было бы...

введите здесь описание изображения введите здесь описание изображения

Обратите внимание, что поток несжатых данных здесь представляет собой красное изображение 50 x 50 в формате rgba с дополнительным байтом на строку для фильтра, в результате чего получается 10 050 байт. То есть 50*50*40+50.


person Dave P    schedule 12.12.2018    source источник
comment
Как указывает Марк Адлер в этом дубликате, контрольная сумма выполняется для предварительно обработанного потока PNG непосредственно перед фактическим сжатием. Таким образом, исходные растровые данные, на которых вы тестировали, близки... но не совсем.   -  person Jongware    schedule 13.12.2018
comment
@ usr2564301, ах, правильно, это дублирующий вопрос. Поток несжатых данных имеет дополнительные биты для альфа-канала (в отличие от исходного файла bmp). Отмечено в файле по адресу 000017:0x0806 и видно при распаковке данных zlib в python.   -  person Dave P    schedule 13.12.2018