Skip to content

Instantly share code, notes, and snippets.

@AlpaGit
Created October 9, 2024 04:11
Show Gist options
  • Select an option

  • Save AlpaGit/b9970e92ed8c05e43c86ab7d8bd25e28 to your computer and use it in GitHub Desktop.

Select an option

Save AlpaGit/b9970e92ed8c05e43c86ab7d8bd25e28 to your computer and use it in GitHub Desktop.
Adler32.c3 implementation
module adler32;
import logger;
// largest prime smaller than 65536
const uint BASE = 65521;
// NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32 - 1
const uint NMAX = 5552;
fn uint hash(char[] input)
{
return adler32_z(1, input);
}
fn uint adler32_z(uint adler, char[] input)
{
uint s1 = adler & 0xffff;
uint s2 = (adler >> 16) & 0xffff;
if (input.len == 1)
{
s1 += input[0];
if (s1 >= BASE)
{
s1 -= BASE;
}
s2 += s1;
if (s2 >= BASE)
{
s2 -= BASE;
}
}
else if (input.len < 16)
{
foreach (b : input)
{
s1 += b;
s2 += s1;
}
if (s1 >= BASE) {
s1 -= BASE;
}
s2 %= BASE;
}
else
{
usz n = NMAX / 16;
usz i = 0;
while(i + NMAX <= input.len)
{
usz rounds = 0;
for (rounds = 0; rounds < n; rounds++)
{
usz j = 0;
for (j = 0; j < 16; j++)
{
s1 += input[i+j];
s2 += s1;
}
i += 16;
}
s1 %= BASE;
s2 %= BASE;
}
if(i < input.len)
{
while(i + 16 <= input.len)
{
usz j = 0;
while(j < 16)
{
s1 += input[i+j];
s2 += s1;
j++;
}
i += 16;
}
while(i < input.len)
{
s1 += input[i];
s2 += s1;
i++;
}
s1 %= BASE;
s2 %= BASE;
}
}
return s1 | (s2 << 16);
}
fn void adler32_test1() @test
{
assert(hash("a") == 0x620062);
}
fn void adler32_test2() @test
{
assert(hash("example") == 0xbc002ed);
}
fn void adler32_test3() @test
{
// generate a 16 byte string
assert(hash("a big string bigger than 16 bytes") == 0xc5020b94);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment