adler.pas 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. uses
  12. zutil;
  13. function adler32(adler : uLong; buf : pBytef; len : uInt) : uLong;
  14. { Update a running Adler-32 checksum with the bytes buf[0..len-1] and
  15. return the updated checksum. If buf is NIL, this function returns
  16. the required initial value for the checksum.
  17. An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
  18. much faster. Usage example:
  19. var
  20. adler : uLong;
  21. begin
  22. adler := adler32(0, Z_NULL, 0);
  23. while (read_buffer(buffer, length) <> EOF) do
  24. adler := adler32(adler, buffer, length);
  25. if (adler <> original_adler) then
  26. error();
  27. end;
  28. }
  29. implementation
  30. const
  31. BASE = Long(65521); { largest prime smaller than 65536 }
  32. {NMAX = 5552; original code with unsigned 32 bit integer }
  33. { NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 }
  34. NMAX = 3854; { code with signed 32 bit integer }
  35. { NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^31-1 }
  36. { The penalty is the time loss in the extra MOD-calls. }
  37. { ========================================================================= }
  38. function adler32(adler : uLong; buf : pBytef; len : uInt) : uLong;
  39. var
  40. s1, s2 : uLong;
  41. k : int;
  42. begin
  43. s1 := adler and $ffff;
  44. s2 := (adler shr 16) and $ffff;
  45. if not Assigned(buf) then
  46. begin
  47. adler32 := uLong(1);
  48. exit;
  49. end;
  50. while (len > 0) do
  51. begin
  52. if len < NMAX then
  53. k := len
  54. else
  55. k := NMAX;
  56. Dec(len, k);
  57. {
  58. while (k >= 16) do
  59. begin
  60. DO16(buf);
  61. Inc(buf, 16);
  62. Dec(k, 16);
  63. end;
  64. if (k <> 0) then
  65. repeat
  66. Inc(s1, buf^);
  67. Inc(puf);
  68. Inc(s2, s1);
  69. Dec(k);
  70. until (k = 0);
  71. }
  72. while (k > 0) do
  73. begin
  74. Inc(s1, buf^);
  75. Inc(s2, s1);
  76. Inc(buf);
  77. Dec(k);
  78. end;
  79. s1 := s1 mod BASE;
  80. s2 := s2 mod BASE;
  81. end;
  82. adler32 := (s2 shl 16) or s1;
  83. end;
  84. {
  85. #define DO1(buf,i)
  86. begin
  87. Inc(s1, buf[i]);
  88. Inc(s2, s1);
  89. end;
  90. #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
  91. #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
  92. #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
  93. #define DO16(buf) DO8(buf,0); DO8(buf,8);
  94. }
  95. end.