Home > ASP.NET > Simple string compression/decompression

Simple string compression/decompression

There have been times where there is a need to compress a string before sending it to a server. However during a string compression, there are cases where the compressed string is longer than the original string.

 

So I’ve written a quick string extension that will cater to such conditions. During compression it encodes it to base64 for transmission and appends a header before the string, since base64 does not contain such characters, there is no worry about corruption

 

The Compress function does a few checks before it really returns a compressed string

  1. Original string must be at least 256 in length, catering for double byte characters, this would mean no encryption will be done for < 512 bytes
  2. Between the original string and compressed string, there needs to be at least a 10% saving in compression, anything lesser will return the original string. This is to reduce the overheads of decompression
  3. To determine whether a compressed string is returned, a special header {*} is appended in front and at the end of the string. this is used by the decompress function to determine if the input string is compressed or uncompressed.

 

Codes as follows:

public static string Compress(this string s)
        {
            string Delimiter = "{*|0}";
            //if lesser than 256 characters (512bytes due to possible double byte encoding), dont bother compressing
            if (s.Length < 256)
                return s;

            //Use the maximum unicode to get the bytes
            var bytes = Encoding.UTF32.GetBytes(s);
            using (var ms0 = new MemoryStream(bytes))
            {
                using (var ms1 = new MemoryStream())
                {
                    using (var gs = new GZipStream(ms1, CompressionMode.Compress))
                    {
                        ms0.CopyTo(gs);
                    }
                    var ec = Delimiter + Convert.ToBase64String(ms1.ToArray()) + Delimiter;

                    //compare source and compressed string, only return compressed string if there is at least 10% savings
                    if ((s.Length – ec.Length)*1.0/s.Length > 0.1)
                        return ec;
                    else
                        return s;
                }
            }
        }

        public static string Decompress(this string s)
        {
            string Delimiter = "{*|0}";
            if (s.IndexOf(Delimiter) == 0 && s.Substring(s.Length – Delimiter.Length, Delimiter.Length) == Delimiter)
            {
                //takes out the front and ending delimiter

                try
                {
                    var bytes = Convert.FromBase64String(s.Substring(Delimiter.Length, s.Length – Delimiter.Length * 2));
                    using (var ms0 = new MemoryStream(bytes))
                    {
                        using (var ms1 = new MemoryStream())
                        {
                            using (var gs = new GZipStream(ms0, CompressionMode.Decompress))
                            {
                                gs.CopyTo(ms1);
                            }
                            return Encoding.UTF32.GetString(ms1.ToArray());
                        }
                    }
                }
                catch (FormatException ex)
                {
                    //if for some reason, base64 decryption fail, we could be looking at a real string
                    if (ex.Message.Contains("Invalid length for a Base-64 char array or string"))
                        return s;
                    else
                        throw ex;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            else
                return s;
        }

Categories: ASP.NET
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: