views:

96

answers:

5

say I want to store ID's in a cookie:

123,1232,3443,2343,2344422,2342

seeing that a cookie has a 4kb limit (or whatever), would encrypting the value allow for more storage somehow?

if so, which encryption would be best? (not really worried about security, just want to store more with less footprint)

A: 

Encryption will not necessarily compress (it usually won't) , and any compression you do can be done without encryption.

Can I suggest you look at Protocol Buffers for an easy way to store simple data like this efficiently.

Nick Fortescue
+2  A: 

Encryption itself isn't going to compress the data. You could look at compressing it though. Keep in mind that different values will compress by different amounts, so if you get near the limits of what can be compressed, you may find that it sometimes doesn't fit. If you're running out of space you may want to look for a different approach instead.

Note that you can't meaningfully compress it after encrypting it. The encryption changes it into seemingly random data and that does not lend itself to compression.

retracile
+5  A: 

With 4k bytes, you can store 819 four digit numbers. Are you sure you really do need to store more?

Wouldn't it be maybe then easier to just store in the cookie a key that would bring you to your overlong sequence of numbers with a simple DB query?

badp
A: 

If you are only interested in compressing the data you could just use the stream compression classes in .Net. http://msdn.microsoft.com/en-us/library/system.io.compression.gzipstream.aspx

David
A: 

You could try small compression on each number using an implementation of VInt/Vlong. Compression will vary on your data. Higher id's will yield lower compression.

Here's an implementation using vint:

class CookieConverter
{
    private readonly Encoding _enc = Encoding.GetEncoding("iso-8859-1");
    public string PackCookieString(List<int> numbers)
    {
        MemoryStream memoryStream = new MemoryStream();
        foreach (int number in numbers)
        {
            byte[] bytes = GetVIntBytes(number);
            memoryStream.Write(bytes, 0, bytes.Length);
        }
        return _enc.GetString(memoryStream.ToArray());
    }

    public List<int> UnpackCookieString(string cookie)
    {
        byte[] bytes = _enc.GetBytes(cookie);
        List<int> numbers = new List<int>();
        int startIndex = 0;
        while (startIndex < bytes.Length)
        {
            numbers.Add(GetVInt(bytes, ref startIndex));
        }
        return numbers;
    }

    public byte[] GetVIntBytes(int value)
    {
        byte[] buffer = new byte[5];
        byte length = 0;
        while ((value & ~0x7F) != 0)
        {
            buffer[length] = (byte) ((value & 0x7f) | 0x80);
            value = value >> 7;
            length++;
        }
        buffer[length] = (byte) value;
        byte[] result = new byte[length+1];
        Array.Copy(buffer, 0, result, 0, result.Length);
        return result;
    }

    public int GetVInt(byte[] buffer, ref int startIndex)
    {
        byte b = buffer[startIndex];
        startIndex++;
        int i = b & 0x7F;
        for (int shift = 7; (b & 0x80) != 0; shift += 7)
        {
            b = buffer[startIndex];
            i |= (b & 0x7F) << shift;
            startIndex++;
        }
        return i;
    }
Mikael Svenson