ZLIB Compression in .NET

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.

Nick Berardi

Entrepreneur, Microsoft MVP, ASPInsider, co-founder and CTO of @CaddioApp, Father, and @SeriouslyOpen host