adler.pas 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. unit adler;
  2. {
  3. adler32.c -- compute the Adler-32 checksum of a data stream
  4. Copyright (C) 1995-1998 Mark Adler
  5. Pascal tranlastion
  6. Copyright (C) 1998 by Jacques Nomssi Nzali
  7. For conditions of distribution and use, see copyright notice in readme.txt
  8. }
  9. interface
  10. {$I zconf.inc}
  11. function adler32(adler : cardinal; buf : Pbyte; len : cardinal) : cardinal;
  12. { Update a running Adler-32 checksum with the bytes buf[0..len-1] and
  13. return the updated checksum. If buf is NIL, this function returns
  14. the required initial value for the checksum.
  15. An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
  16. much faster. Usage example:
  17. var
  18. adler : cardinal;
  19. begin
  20. adler := adler32(0, nil, 0);
  21. while (read_buffer(buffer, length) <> EOF) do
  22. adler := adler32(adler, buffer, length);
  23. if (adler <> original_adler) then
  24. error();
  25. end;
  26. }
  27. implementation
  28. const
  29. BASE = cardinal(65521); { largest prime smaller than 65536 }
  30. {NMAX = 5552; original code with unsigned 32 bit integer }
  31. { NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 }
  32. NMAX = 3854; { code with signed 32 bit integer }
  33. { NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^31-1 }
  34. { The penalty is the time loss in the extra MOD-calls. }
  35. { ========================================================================= }
  36. function adler32(adler : cardinal; buf : Pbyte; len : cardinal) : cardinal;
  37. var
  38. s1, s2 : cardinal;
  39. k : integer;
  40. begin
  41. s1 := adler and $ffff;
  42. s2 := (adler shr 16) and $ffff;
  43. if not Assigned(buf) then
  44. begin
  45. adler32 := cardinal(1);
  46. exit;
  47. end;
  48. while (len > 0) do
  49. begin
  50. if len < NMAX then
  51. k := len
  52. else
  53. k := NMAX;
  54. Dec(len, k);
  55. {
  56. while (k >= 16) do
  57. begin
  58. DO16(buf);
  59. Inc(buf, 16);
  60. Dec(k, 16);
  61. end;
  62. if (k <> 0) then
  63. repeat
  64. Inc(s1, buf^);
  65. Inc(puf);
  66. Inc(s2, s1);
  67. Dec(k);
  68. until (k = 0);
  69. }
  70. while (k > 0) do
  71. begin
  72. Inc(s1, buf^);
  73. Inc(s2, s1);
  74. Inc(buf);
  75. Dec(k);
  76. end;
  77. s1 := s1 mod BASE;
  78. s2 := s2 mod BASE;
  79. end;
  80. adler32 := (s2 shl 16) or s1;
  81. end;
  82. {
  83. #define DO1(buf,i)
  84. begin
  85. Inc(s1, buf[i]);
  86. Inc(s2, s1);
  87. end;
  88. #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
  89. #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
  90. #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
  91. #define DO16(buf) DO8(buf,0); DO8(buf,8);
  92. }
  93. end.