/* ********************************************************************* * Description: The following source code is borrowed heavily from the * zlib project The zlib source is subject to the following copyright * and license: * * Copyright (C) 1995-2010, 2021 Jean-loup Gailly and Mark Adler * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * * Jean-loup Gailly Mark Adler * jloup@gzip.org madler@alumni.caltech.edu */ #include "adler.h" #define DO1(buf, i) \ { \ s1 += (buf)[i]; \ s2 += s1; \ } #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); size_t adler(size_t adler, const void *vbuf, size_t len) { const size_t BASE = 65521; /* largest prime smaller than 65536 */ const size_t NMAX = 5552; /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ const unsigned char *buf = (const unsigned char *)vbuf; size_t s1 = adler & 0xffff; size_t s2 = (adler >> 16) & 0xffff; if (buf == NULL || len == 0) { return 1L; } while (len > 0) { int k = len < NMAX ? len : NMAX; len -= k; while (k >= 16) { DO16(buf); buf += 16; k -= 16; } if (k != 0) { do { s1 += *buf++; s2 += s1; } while (--k); } s1 %= BASE; s2 %= BASE; } return (s2 << 16) | s1; }