zlib-adler32.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /* zlib-adler32.js -- JavaScript implementation for the zlib adler32.
  2. Version: 0.2.0
  3. LastModified: Apr 12 2012
  4. Copyright (C) 2012 Masanao Izumo <[email protected]>
  5. API documentation
  6. ==============================================================================
  7. Usage: adler = ZLIB.adler32(adler, buf, offset, len);
  8. Update a running Adler-32 checksum with the bytes buf[offset..offset+len-1] and
  9. return the updated checksum. If buf is null, this function returns the
  10. required initial value for the checksum.
  11. An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
  12. much faster.
  13. Usage example:
  14. var adler = ZLIB.adler32(0, null, 0, 0);
  15. while (read_buffer(buffer, length) != EOF) {
  16. adler = ZLIB.adler32(adler, buffer, 0, length);
  17. }
  18. if (adler != original_adler) error();
  19. ==============================================================================
  20. Usage: adler = ZLIB.adler32_combine(adler1, adler2, len2);
  21. Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
  22. and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
  23. each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
  24. seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
  25. that the z_off_t type (like off_t) is a signed integer. If len2 is
  26. negative, the result has no meaning or utility.
  27. */
  28. if( typeof ZLIB === 'undefined' ) {
  29. alert('ZLIB is not defined. SRC zlib.js before zlib-adler32.js')
  30. }
  31. (function() {
  32. /* adler32.c -- compute the Adler-32 checksum of a data stream
  33. * Copyright (C) 1995-2011 Mark Adler
  34. * For conditions of distribution and use, see copyright notice in zlib.h
  35. */
  36. var BASE = 65521; /* largest prime smaller than 65536 */
  37. var NMAX = 5552;
  38. /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
  39. /* ========================================================================= */
  40. function adler32_string(adler, buf, offset, len)
  41. {
  42. var sum2;
  43. var n;
  44. /* split Adler-32 into component sums */
  45. sum2 = (adler >>> 16) & 0xffff;
  46. adler &= 0xffff;
  47. /* in case user likes doing a byte at a time, keep it fast */
  48. if (len == 1) {
  49. adler += buf.charCodeAt(offset) & 0xff;
  50. if (adler >= BASE)
  51. adler -= BASE;
  52. sum2 += adler;
  53. if (sum2 >= BASE)
  54. sum2 -= BASE;
  55. return adler | (sum2 << 16);
  56. }
  57. /* initial Adler-32 value (deferred check for len == 1 speed) */
  58. if (buf === null)
  59. return 1;
  60. /* in case short lengths are provided, keep it somewhat fast */
  61. if (len < 16) {
  62. while (len--) {
  63. adler += buf.charCodeAt(offset++) & 0xff;
  64. sum2 += adler;
  65. }
  66. if (adler >= BASE)
  67. adler -= BASE;
  68. sum2 %= BASE; /* only added so many BASE's */
  69. return adler | (sum2 << 16);
  70. }
  71. /* do length NMAX blocks -- requires just one modulo operation */
  72. while (len >= NMAX) {
  73. len -= NMAX;
  74. n = NMAX >> 4; /* NMAX is divisible by 16 */
  75. do {
  76. /* 16 sums unrolled */
  77. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  78. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  79. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  80. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  81. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  82. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  83. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  84. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  85. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  86. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  87. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  88. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  89. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  90. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  91. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  92. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  93. } while (--n);
  94. adler %= BASE;
  95. sum2 %= BASE;
  96. }
  97. /* do remaining bytes (less than NMAX, still just one modulo) */
  98. if (len) { /* avoid modulos if none remaining */
  99. while (len >= 16) {
  100. len -= 16;
  101. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  102. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  103. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  104. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  105. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  106. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  107. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  108. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  109. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  110. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  111. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  112. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  113. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  114. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  115. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  116. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  117. }
  118. while (len--) {
  119. adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
  120. }
  121. adler %= BASE;
  122. sum2 %= BASE;
  123. }
  124. /* return recombined sums */
  125. return adler | (sum2 << 16);
  126. }
  127. /* ========================================================================= */
  128. function adler32_array(adler, buf, offset, len)
  129. {
  130. var sum2;
  131. var n;
  132. /* split Adler-32 into component sums */
  133. sum2 = (adler >>> 16) & 0xffff;
  134. adler &= 0xffff;
  135. /* in case user likes doing a byte at a time, keep it fast */
  136. if (len == 1) {
  137. adler += buf[offset];
  138. if (adler >= BASE)
  139. adler -= BASE;
  140. sum2 += adler;
  141. if (sum2 >= BASE)
  142. sum2 -= BASE;
  143. return adler | (sum2 << 16);
  144. }
  145. /* initial Adler-32 value (deferred check for len == 1 speed) */
  146. if (buf === null)
  147. return 1;
  148. /* in case short lengths are provided, keep it somewhat fast */
  149. if (len < 16) {
  150. while (len--) {
  151. adler += buf[offset++];
  152. sum2 += adler;
  153. }
  154. if (adler >= BASE)
  155. adler -= BASE;
  156. sum2 %= BASE; /* only added so many BASE's */
  157. return adler | (sum2 << 16);
  158. }
  159. /* do length NMAX blocks -- requires just one modulo operation */
  160. while (len >= NMAX) {
  161. len -= NMAX;
  162. n = NMAX >> 4; /* NMAX is divisible by 16 */
  163. do {
  164. /* 16 sums unrolled */
  165. adler += buf[offset++]; sum2 += adler;
  166. adler += buf[offset++]; sum2 += adler;
  167. adler += buf[offset++]; sum2 += adler;
  168. adler += buf[offset++]; sum2 += adler;
  169. adler += buf[offset++]; sum2 += adler;
  170. adler += buf[offset++]; sum2 += adler;
  171. adler += buf[offset++]; sum2 += adler;
  172. adler += buf[offset++]; sum2 += adler;
  173. adler += buf[offset++]; sum2 += adler;
  174. adler += buf[offset++]; sum2 += adler;
  175. adler += buf[offset++]; sum2 += adler;
  176. adler += buf[offset++]; sum2 += adler;
  177. adler += buf[offset++]; sum2 += adler;
  178. adler += buf[offset++]; sum2 += adler;
  179. adler += buf[offset++]; sum2 += adler;
  180. adler += buf[offset++]; sum2 += adler;
  181. } while (--n);
  182. adler %= BASE;
  183. sum2 %= BASE;
  184. }
  185. /* do remaining bytes (less than NMAX, still just one modulo) */
  186. if (len) { /* avoid modulos if none remaining */
  187. while (len >= 16) {
  188. len -= 16;
  189. adler += buf[offset++]; sum2 += adler;
  190. adler += buf[offset++]; sum2 += adler;
  191. adler += buf[offset++]; sum2 += adler;
  192. adler += buf[offset++]; sum2 += adler;
  193. adler += buf[offset++]; sum2 += adler;
  194. adler += buf[offset++]; sum2 += adler;
  195. adler += buf[offset++]; sum2 += adler;
  196. adler += buf[offset++]; sum2 += adler;
  197. adler += buf[offset++]; sum2 += adler;
  198. adler += buf[offset++]; sum2 += adler;
  199. adler += buf[offset++]; sum2 += adler;
  200. adler += buf[offset++]; sum2 += adler;
  201. adler += buf[offset++]; sum2 += adler;
  202. adler += buf[offset++]; sum2 += adler;
  203. adler += buf[offset++]; sum2 += adler;
  204. adler += buf[offset++]; sum2 += adler;
  205. }
  206. while (len--) {
  207. adler += buf[offset++]; sum2 += adler;
  208. }
  209. adler %= BASE;
  210. sum2 %= BASE;
  211. }
  212. /* return recombined sums */
  213. return adler | (sum2 << 16);
  214. }
  215. /* ========================================================================= */
  216. ZLIB.adler32 = function(adler, buf, offset, len)
  217. {
  218. if(typeof buf === 'string') {
  219. return adler32_string(adler, buf, offset, len);
  220. } else {
  221. return adler32_array(adler, buf, offset, len);
  222. }
  223. };
  224. ZLIB.adler32_combine = function(adler1, adler2, len2)
  225. {
  226. var sum1;
  227. var sum2;
  228. var rem;
  229. /* for negative len, return invalid adler32 as a clue for debugging */
  230. if (len2 < 0)
  231. return 0xffffffff;
  232. /* the derivation of this formula is left as an exercise for the reader */
  233. len2 %= BASE; /* assumes len2 >= 0 */
  234. rem = len2;
  235. sum1 = adler1 & 0xffff;
  236. sum2 = rem * sum1;
  237. sum2 %= BASE;
  238. sum1 += (adler2 & 0xffff) + BASE - 1;
  239. sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
  240. if (sum1 >= BASE) sum1 -= BASE;
  241. if (sum1 >= BASE) sum1 -= BASE;
  242. if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
  243. if (sum2 >= BASE) sum2 -= BASE;
  244. return sum1 | (sum2 << 16);
  245. }
  246. }());