2011-05-30 86 views
3

我使用zlib中的adler32函数来计算一块内存x(长度为4096)的弱校验和。一切都很好,但现在我想执行滚动校验和,如果来自不同文件的块不匹配,但是,我不知道如何编写函数来执行对zlib中adler32返回值的函数。因此,如果校验和不匹配,我如何使用原始校验和x + 1字节和x + 4096 + 1来计算滚动校验和?基本上试图构建rsync实现。Zlib adler32滚动校验和问题

谢谢先进。

+1

rsync不直接使用adler32。他们修改了一下,可能会使复发更简单? – 2011-08-10 22:02:15

回答

5

Pysync已实施滚动的zlib的的Adler32的顶部是这样的:

_BASE=65521  # largest prime smaller than 65536 
_NMAX=5552  # largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 
_OFFS=1   # default initial s1 offset 
import zlib 
class adler32: 
    def __init__(self,data=''): 
     value = zlib.adler32(data,_OFFS) 
     self.s2, self.s1 = (value >> 16) & 0xffff, value & 0xffff 
     self.count=len(data) 
    def update(self,data): 
     value = zlib.adler32(data, (self.s2<<16) | self.s1) 
     self.s2, self.s1 = (value >> 16) & 0xffff, value & 0xffff 
     self.count = self.count+len(data) 
    def rotate(self,x1,xn): 
     x1,xn=ord(x1),ord(xn) 
     self.s1=(self.s1 - x1 + xn) % _BASE 
     self.s2=(self.s2 - self.count*x1 + self.s1 - _OFFS) % _BASE 
    def digest(self): 
     return (self.s2<<16) | self.s1 
    def copy(self): 
     n=adler32() 
     n.count,n.s1,n.s2=self.count,self.s1,self.s2 
     return n 

但彼得说,rsync的不使用的Adler32直接,但它的速度更快的变体。

rsync工具的代码有点难以阅读,但结帐librsync。这是一个完全独立的项目,它更具可读性。看看rollsum.crollsum.h。在C宏中有一种有效的变体实现:

/* the Rollsum struct type*/ 
typedef struct _Rollsum { 
    unsigned long count;    /* count of bytes included in sum */ 
    unsigned long s1;     /* s1 part of sum */ 
    unsigned long s2;     /* s2 part of sum */ 
} Rollsum; 

#define ROLLSUM_CHAR_OFFSET 31 

#define RollsumInit(sum) { \ 
    (sum)->count=(sum)->s1=(sum)->s2=0; \ 
} 

#define RollsumRotate(sum,out,in) { \ 
    (sum)->s1 += (unsigned char)(in) - (unsigned char)(out); \ 
    (sum)->s2 += (sum)->s1 - (sum)->count*((unsigned char)(out)+ROLLSUM_CHAR_OFFSET); \ 
} 

#define RollsumRollin(sum,c) { \ 
    (sum)->s1 += ((unsigned char)(c)+ROLLSUM_CHAR_OFFSET); \ 
    (sum)->s2 += (sum)->s1; \ 
    (sum)->count++; \ 
} 

#define RollsumRollout(sum,c) { \ 
    (sum)->s1 -= ((unsigned char)(c)+ROLLSUM_CHAR_OFFSET); \ 
    (sum)->s2 -= (sum)->count*((unsigned char)(c)+ROLLSUM_CHAR_OFFSET); \ 
    (sum)->count--; \ 
} 

#define RollsumDigest(sum) (((sum)->s2 << 16) | ((sum)->s1 & 0xffff)) 
+0

这个例子中的ROLLSUM_CHAR_OFFSET是什么,它为什么是31?散列描述中没有这样的东西。 – 2015-01-10 20:26:15