123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- unit adler;
- {
- adler32.c -- compute the Adler-32 checksum of a data stream
- Copyright (C) 1995-1998 Mark Adler
- Pascal tranlastion
- Copyright (C) 1998 by Jacques Nomssi Nzali
- For conditions of distribution and use, see copyright notice in readme.txt
- }
- interface
- {$I zconf.inc}
- function adler32(adler : cardinal; buf : Pbyte; len : cardinal) : cardinal;
- { Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NIL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
- var
- adler : cardinal;
- begin
- adler := adler32(0, nil, 0);
- while (read_buffer(buffer, length) <> EOF) do
- adler := adler32(adler, buffer, length);
- if (adler <> original_adler) then
- error();
- end;
- }
- implementation
- const
- BASE = cardinal(65521); { largest prime smaller than 65536 }
- {NMAX = 5552; original code with unsigned 32 bit integer }
- { NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 }
- NMAX = 3854; { code with signed 32 bit integer }
- { NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^31-1 }
- { The penalty is the time loss in the extra MOD-calls. }
- { ========================================================================= }
- function adler32(adler : cardinal; buf : Pbyte; len : cardinal) : cardinal;
- var
- s1, s2 : cardinal;
- k : integer;
- begin
- s1 := adler and $ffff;
- s2 := (adler shr 16) and $ffff;
- if not Assigned(buf) then
- begin
- adler32 := cardinal(1);
- exit;
- end;
- while (len > 0) do
- begin
- if len < NMAX then
- k := len
- else
- k := NMAX;
- Dec(len, k);
- {
- while (k >= 16) do
- begin
- DO16(buf);
- Inc(buf, 16);
- Dec(k, 16);
- end;
- if (k <> 0) then
- repeat
- Inc(s1, buf^);
- Inc(puf);
- Inc(s2, s1);
- Dec(k);
- until (k = 0);
- }
- while (k > 0) do
- begin
- Inc(s1, buf^);
- Inc(s2, s1);
- Inc(buf);
- Dec(k);
- end;
- s1 := s1 mod BASE;
- s2 := s2 mod BASE;
- end;
- adler32 := (s2 shl 16) or s1;
- end;
- {
- #define DO1(buf,i)
- begin
- Inc(s1, buf[i]);
- Inc(s2, s1);
- end;
- #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
- #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
- #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
- #define DO16(buf) DO8(buf,0); DO8(buf,8);
- }
- end.
|