Adler-32是一种校验算法,由马克·阿德勒(英语:Mark Adler)在1995年发明,是对Fletcher校验(英语:Fletcher's checksum)的一种改进。与相同长度的循环冗余校验相比,它以可靠性换取速度(更倾向于后者)。Adler-32比Fletcher-16(英语:Fletcher-16)更加可靠,比Fletcher-32(英语:Fletcher-32)可靠性稍差。
Adler-32校验和是广泛使用的zlib压缩库的一部分,因为两者都是由马克·阿德勒(英语:Mark Adler)开发的。在rsync工具中使用了Adler-32的“旋转哈希”版本。
Adler-32校验和是通过计算两个16位的校验和和,并将它们的位连为一个32位整数来获得的。是流中所有字节的总和加1,而是每个步骤中的各个值的总和。在Adler-32运行开始时,被初始化为1,为0。以模65521(小于216的最大质数)进行求和。字节以网络顺序存储(字节序),占据最高的两个字节。
该函数可以表示为
= 1 + 1 + 2 + ... + (mod 65521) = (1 + 1) + (1 + 1 + 2) + ... + (1 + 1 + 2 + ... + ) (mod 65521) = ×1 + (−1)×2 + (−2)×3 + ... + + (mod 65521)() = × 65536 +
其中是要计算校验和的字节串,是的长度。
ASCII字符串“ Wikipedia
”的Adler-32校验和计算如下:
A = 920 = 0x398 (16进制)B = 4582 = 0x11E6输出 = 0x11E6 << 16 + 0x398 = 0x11E60398
在这个例子中,取模运算没有效果,因为没有一个值达到65521。
两种算法之间的第一个区别,是Adler-32和是以一个质数为模数计算的,而Fletcher和是以24-1、28-1或216-1为模(取决于所使用的位数)为模数计算的,它们都是复合数。使用质数使得Adler-32可以捕获到Fletcher无法检测到的某些字节组合中的差异。
第二个区别,也是对算法的速度影响最大的区别,是Adler和是在8位的字节上计算的,而不是16位的字上,导致循环迭代次数增加了一倍。 这使得对于16位字对齐数据,Adler-32校验和花的时间是Fletcher校验和的1.5到2倍。对于字节对齐的数据,Adler-32比正确实现的Fletcher的校验和(例如,HDF中的实现)要快。
在C语言中,一个低效但直接的实现方式是:
const uint32_t MOD_ADLER = 65521;uint32_t adler32(unsigned char *data, size_t len) /* where data is the location of the data in physical memory and len is the length of the data in bytes */{ uint32_t a = 1, b = 0; size_t index; // Process each byte of the data in order for (index = 0; index < len; ++index) { a = (a + data) % MOD_ADLER; b = (b + a) % MOD_ADLER; } return (b << 16) | a;}