DataCompression module generates a different adler32 checksum
TomBowden2019 opened this issue · 2 comments
Marcus,
I hate getting issues where someone says "there is a problem in your code..."
without giving details... so I hope you'll forgive my verbosity.
In C++, the following will generate a checksum of 0xA490238:
std::string test_string = "TEST CRC";
unsigned int a32 = adler32(0L, (Bytef *)test_string.data(), test_string.length());
With the DataCompression module the same string generates a checksum of 0xA490239:
let test_crc = "TEST CRC"
var a32 = Adler32()
a32.advance(withChunk: test_crc.data(using:.utf8)!)
print ( "a32 = \(a32)" )
The issue appears to be related to the initialization of checksum for adler32:
--- DataCompression.swift:384 ---
/// Raw checksum. Updated after a every call to `advance(withChunk:)`
public var checksum:UInt32 = 1
--- DataCompression.swift:384 ---
In zlib/adler32, a 1L is returned only if the chunk being evaluated is null.
Otherwise, checksum starts with 0.
--- zlib-1.2.11/adler32.c:87 ---
if (buf == Z_NULL)
return 1L;
--- zlib-1.2.11/adler32.c:87 ---
Suggested fix:
initialize checksum to 0 (DataCompression.swift:385) and then,when returning checksum, return 1 if checksum == 0
--- DataCompression.swift:402 ---
/// Formatted checksum.
public var description: String
{
if checksum == 0 { // THB
return "1" // THB
} // THB
return String(format: "%08x", checksum)
}
--- DataCompression.swift:402 ---
You would still have to account for checksum being read in other ways...
Thanks!
Tom Bowden
email: tommyBowden2014@gmail.com
I hate getting issues where someone says "there is a problem in your code..."
without giving details... so I hope you'll forgive my verbosity.
Hi. No problem. I take on every issue :) Unfortunately, I believe there is problem in YOUR code 😄
If you use zlib in C or C++, instead of 0L
you need the initial adler32 value. So I suggest you try adler32(0L, Z_NULL, 0);
to get the initial value like:
uLong adler = adler32(0L, Z_NULL, 0);
while (read_buffer(buffer, length) != EOF) {
adler = adler32(adler, buffer, length);
}
if (adler != original_adler) error();
(Please close this issue if it solves your problem.)
Such a mixed blessing to be proven wrong. Now I have to go back through all of my code where I missed that.
Thanks for the illumination!
Tom