Slight Problem when using Crc Builder and the ADLER32 algorithm

One of the users of the Crc Builder programs mentioned a problem with the CRC generated as it did not conform to the expected value when run against a known data set. The problem is the starting seed to the first call to the module supplied by the ZLIB people. A closer look at the code has shown me where I was going (or not) wrong.

Here is a link to the Wiki the test profile came from.
http://en.wikipedia.org/wiki/Adler-32

According to the Wikipedia entry for Adler-32, the data Wikipedia should result in a checksum of 300286872. Ours is producing 299697047 (This is after we converted the buffer to ASCII). or you could simply have x’57’ x’69’ x’6B’ x’69’ x’70’ x’65’ x’64’ x’69’ x’61’ in the data buffer(thanks to Chris Edmonson for that)..

So we looked at how exactly this was being generated, the final check sum gave us no idea where the problem lay but on review of the Wiki information we picked up on the following.

ASCII code A B
(shown as base 10)
W: 87 1 + 87 = 88 0 + 88 = 88
i: 105 88 + 105 = 193 88 + 193 = 281
k: 107 193 + 107 = 300 281 + 300 = 581
i: 105 300 + 105 = 405 581 + 405 = 986
p: 112 405 + 112 = 517 986 + 517 = 1503
e: 101 517 + 101 = 618 1503 + 618 = 2121
d: 100 618 + 100 = 718 2121 + 718 = 2839
i: 105 718 + 105 = 823 2839 + 823 = 3662
a: 97 823 + 97 = 920 3662 + 920 = 4582
A = 920 = 398 hex (base 16)
B = 4582 = 11E6 hex
Output = 300286872 = 11E60398 hex

You will see that the starting point for the final CRC was 1. When we called the function in our program it was being passed 0, so the end result while consistent never matched the expected output.

So we then started to look at the code as shipped by ZLIB people and found this piece of code
/* initial Adler-32 value (deferred check for len == 1 speed) */
if (buf == Z_NULL)
return 1L;

Here is the suggested code for calling the function.

define Z_NULL 0
uLong adler = adler32(0L, Z_NULL, 0);
while (read_buffer(buffer, length) != EOF) {
adler = adler32(adler, buffer, length);
}
if (adler != original_adler) error();

Our solution was very simple we simply initialized the adler variable to 1 on the first call with valid data! Made much more sense than calling the function just to get it set to 1?

uLong adler = 1;
adler = adler32(adler,buffer,buf_len);

We are not mathematicians so we are not sure of the impact of this, however we have posted a new version here

[download#7#image]
Have fun!

Chris…

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.