Как вычислить 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.