Adler-32

✍ dations ◷ 2025-11-20 13:07:21 #校验和算法

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;}

请参阅zlib源代码,了解更有效的实现,它需要对每个字节进行一次取数和两次加法,模数运算延后,并每隔几千个字节计算两次余数,这种技术最早是在1988年被发现用于Fletcher校验。js-adler32也提供了类似的优化,增加了一个技巧,即推迟计算65536-65521中的“15”,这样模数运算就会变得更快:可以证明((a >> 16) * 15 + (a & 65535)) % 65521相当于简单的积累。

对于短消息来说,Adler-32是很弱的,因为总和不会回绕(英语:Integer overflow)(英语:Wrap,即整数溢出后的处理)。128字节消息的最大和是32640,低于取模操作所使用的值65521,这意味着大约有一半的输出空间未使用,并且使用部分内的分布也是不均匀的。延伸的解释可以在RFC 3309中找到,它规定流控制传输协议SCTP使用CRC32C而不是Adler-32。对于较小的增量更改,Adler-32也被证明变化很弱,并且对于从一个共同的前缀和连续的数字生成的字符串也很弱(例如由典型代码生成器自动生成的标签名)。

相关

  • 罗克福干酪罗克福干酪 (法语:le Roquefort),又译“洛克福奶酪”,是羊奶蓝霉干酪的一种,产于法国南部的塔恩河附近圣阿夫里克(Saint-Affrique)镇苏宗尔河畔的罗克福尔(Roquefort-sur-Soulzon)村。
  • 面部神经麻痹贝尔氏麻痹症(Bell's palsy)是面部瘫痪之一种,由颅神经VII(面神经)的功能障碍引起,导致无力控制受影响一侧的面部肌肉。通常受影响一侧眼睛不能闭合。眼睛必须防止干燥,否则角膜可
  • 美司钠美司钠(INN:Mesna,发音: /ˈmɛznə/),又名巯乙磺酸钠,是一种主要用于辅助环磷酰胺和异环磷酰胺化疗的有机硫化合物。它由百特国际以Uromitexan和Mesnex作为商品名销售。它的英文名
  • 旧金山城市铁路4英尺8 1⁄2英寸(1,435毫米)(轻轨)旧金山城市铁路(英语:San Francisco Municipal Railway,简称MUNI)是美国加州旧金山公共交通的管理经营政府机构,是世界上拥有最多元化运营车种的城
  • 台铁LDK50型蒸汽机车台铁LDK50型蒸汽机车为台湾铁路管理局于台东线的客货两用蒸汽机车,总数达到13辆而成为台东线蒸汽机车中的主力。LDK50型自1915年开始引进,直至1982年台东线轨距拓宽为1,067mm
  • 唐勇唐勇(1964年9月12日-),四川井研人。有机化学家。1986年毕业于四川师范大学化学系,1992年和1996年在中国科学院上海有机化学研究所分别获硕士学位和博士学位。1996年3月至1996年7
  • 清齿无咝塞擦音清齿无咝塞擦音是一种辅音,使用于一些口语中。国际音标写作⟨t͡θ⟩、⟨t͜θ⟩、⟨t̪͡θ⟩或⟨t̟͡θ⟩。清齿无咝塞擦音的特征包括:当符号成对出现时,左边的是清音,右边的
  • 深红的金子《深红的金子》(波斯语:طلای سرخ Talaye Sorkh‎) 是一部2003年贾法·帕纳西执导、阿巴斯·奇亚罗斯塔米编剧的伊朗电影。影片获得2003年戛纳影展一种关注单元评审团
  • 莫桑石莫桑石(英语:moissanite)或称摩星石,是天然碳化硅晶体的别称,因1893年由法国化学家亨利·莫瓦桑(Henri Moissan,1852~1907)最先发现而得名。天然碳化硅在地球的自然界中极其罕见,只在
  • 萧大亨《吉安城西萧氏族谱》之萧大亨像萧大亨(1532年-1612年),字夏卿,号岳峰,山东泰安州放城里(今泰安市新泰市放城镇)人,祖籍江西吉水县。明朝政治人物。年幼家贫,其父迁居泰安府城,贩卖豆腐