function adler32(str) {
var a = 1, b = 0, L = str.length, M = 0, c = 0, d = 0;
for (var i = 0; i < L;) {
M = Math.min(L - i, 3850);
while (M > 0) {
c = str.charCodeAt(i++);
if (c < 0x80) { a += c; }
else if (c < 0x800) {
a += 192 | ((c >> 6) & 31); b += a; --M;
a += 128 | (c & 63);
} else if (c >= 0xD800 && c < 0xE000) {
c = (c & 1023) + 64; d = str.charCodeAt(i++) & 1023;
a += 240 | ((c >> 8) & 7); b += a; --M;
a += 128 | ((c >> 2) & 63); b += a; --M;
a += 128 | ((d >> 6) & 15) | ((c & 3) << 4); b += a; --M;
a += 128 | (d & 63);
} else {
a += 224 | ((c >> 12) & 15); b += a; --M;
a += 128 | ((c >> 6) & 63); b += a; --M;
a += 128 | (c & 63);
}
b += a; --M;
}
a = (15 * (a >>> 16) + (a & 65535));
b = (15 * (b >>> 16) + (b & 65535));
}
return ((b % 65521) << 16) | (a % 65521);
}
console.log(adler32('test', 31)); // 73204161
console.log(adler32('abc', 31)); // 38600999
console.log(adler32('abb', 31)); // 38535462