I noticed that zlib’s adler32 function does not always return the original seed when passed an empty string. For example:
adler32(0xFFFFFFFF, // seed
(const Bytef *) "", // buffer
0 // length
)
returns 0xE000E. I would think it should return 0xFFFFFFFF instead.
For most other values, it does return the original seed. However, for 1965855 numbers from 0 to 0xFFFFFFFF, adler32 changes the seed when the input string is empty.
Is this a bug or quirky behavior of the implementation, or is the range of the Adler-32 function in fact a subset of [0,0xFFFFFFFF] ?
Note that when the pointer is NULL, adler32 always returns 1 (the initial seed). This is documented behavior.
The first argument is not a “seed”. It is the previous adler32 value that is being appended to.
Yes, the range of adler32 is not all 32-bit values. 0xffffffff is not a valid adler32. The only valid adler32 values are those in which the upper and lower 16-bit halves of the 32-bit value are, when interpreted as integers, both less than 65521. When you call adler32() with a zero length, it will return the upper and lower halves modulo 65521.
1965855 is 65521*15 + 15*65521 + 15*15, which is the number of 32-bit values with a valid upper half and invalid lower half, plus the number with an invalid upper half and a valid lower half, plus the number with both halves invalid.