Created
October 9, 2024 04:11
-
-
Save AlpaGit/b9970e92ed8c05e43c86ab7d8bd25e28 to your computer and use it in GitHub Desktop.
Adler32.c3 implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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