Adler-32算法

来源:互联网 发布:淘宝店铺违规扣48分 编辑:程序博客网 时间:2024/05/16 04:20


Adler-32 是一个简单的校验和算法,但这个 JAVA 实现还是非常复杂,很难看清楚位操作之间的关系。

以下是 Adler-32 算法的 Haskell 实现:

-- file: ch04/Adler32.hsimport Data.Char (ord)import Data.Bits (shiftL, (.&.), (.|.))base = 65521adler32 xs = helper 1 0 xs    where helper a b (x:xs) = let a' = (a + (ord x .&. 0xff)) `mod` base                                  b' = (a' + b) `mod` base                              in helper a' b' xs          helper a b []     = (b `shiftL` 16) .|. a

在这段代码里, shiftL 函数实现逻辑左移, (.&.) 实现二进制位的并操作, (.|.) 实现二进制位的或操作, ord 函数则返回给定字符对应的编码值。

helper 函数通过尾递归来进行计算,每次对它的调用,都产生新的累积变量,效果等同于 JAVA 在 for 循环里对变量的赋值更新。当列表处理完毕,递归终止时,程序计算出校验和并将它返回。

和前面抽取出 map  filter 函数类似,从 Adler32 函数里面,我们也可以抽取出一种通用的抽象,称之为折叠(fold):它对一个列表中的所有元素做某种处理,并且一边处理元素,一边更新累积器,最后在处理完整个列表之后,返回累积器的值。

有两种不同类型的折叠,其中 foldl 从左边开始进行折叠,而 foldr 从右边开始进行折叠。

0 0