首页 > 解决方案 > 如何在 zlib 中计算 Adler32

问题描述

关于 zlib 中使用的校验和 adler32。

从 RFC 1950 开始:

ADLER32:这包含根据 Adler-32 算法计算的未压缩数据(不包括任何字典数据)的校验和值。

这是一个 png(IDAT 中的 zlib)。 在此处输入图像描述

现在解析灰色数据并将 zlib 数据传递给计算 adler32 的外部程序。

在此处输入图像描述

结果是 64c60bbd,而不是 b0337596。


...或从图像映射传递数据时。

在此处输入图像描述

结果是 1a49bac4,而不是 b0337596


checksum.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 的adler32 的输入数据到底是什么?

解决方案:

如前所述,zlib adler32 是通过未压缩的数据流计算的,在 png 中是过滤后的数据流。在这种情况下,那将是...

在此处输入图像描述 在此处输入图像描述

注意,这里的未压缩数据流是一个红色 50x50 的 rgba 图像,过滤器每行增加一个字节,结果为 10,050 个字节。即 50*50*40 + 50。

标签: pngzlibchecksumadler32

解决方案


推荐阅读