I recently encountered a situation where I needed to provide a compressed byte stream to Java's Inflator class. This probably isn't a situation that you run into a lot as a .NET developer, but to make a long story short, my FluentCassandra library had to send a compressed byte stream to the database server in order to execute a query.
The part that got me scratching my head is the fact that nothing in .NET Framework mentions ZLIB as a supportable compression type. So I had to start hunting down the specification and found that you can actually generate ZLIB compatible compression with the DeflateStream. However the format that Java and other libraries expect has a header in the stream as well as an adler-32 checksum at the end.
Here is the solution that I came up with that can be seen below and also on GitHub's Gist.
public static byte[] ZlibCompress(byte[] data) { using (MemoryStream outStream = new MemoryStream()) { // zlib header outStream.WriteByte(0x58); outStream.WriteByte(0x85); // zlib body using (var compressor = new DeflateStream(outStream, CompressionMode.Compress, true)) compressor.Write(data, 0, data.Length); // zlib checksum - a naive implementation of adler-32 checksum const uint A32Mod = 65521; uint s1 = 1, s2 = 0; foreach (byte b in data) { s1 = (s1 + b) % A32Mod; s2 = (s2 + s1) % A32Mod; } int adler32 = unchecked((int)((s2 << 16) + s1)); outStream.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(adler32)), 0, sizeof(uint)); // zlib compatible compressed query var bytes = outStream.ToArray(); outStream.Close(); return bytes; } }
I am putting this code out there, so nobody else has to hunt for hours trying to find a solution that should be built into .NET given the popularity of the ZLIB compression format.