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

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

От rfc 1950:

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

Вот png (zlib в IDAT).

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

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

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


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

https://stackru.com/images/ce716d70632e458615b354713258c242a fcad0fa.png

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


Код checkum.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;
  }
}

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

Решение:

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

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

0 ответов

Другие вопросы по тегам