关于 zlib 中使用的校验和 adler32。
从 RFC 1950 开始:
ADLER32:这包含根据 Adler-32 算法计算的未压缩数据(不包括任何字典数据)的校验和值。
- 蓝色 = 长度,4 个字节
- 红色 = 类型,4 个字节
- 黄色 = crc,4 个字节
- 绿色 = zlib 标头,2 个字节
- gray = zlib 数据,不同的字节
- 粉红色 = adler32,4 个字节
现在解析灰色数据并将 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。