Q:

Serialize a object to the smallest UTF8 compatible size

I've got an quite simple class that contains some primitive types and some collections with mostly enums. Now I need to serialize this object to the smallest possible size that is UTF8 compatible.
This is the class I need to serialize
public class Context
{
    public Hashtable UserModuleRoles { get; set; }
    public Dictionary<string, object> CustomSettings { get; set; }
    public int Uid { get; set; }
    public int Id { get; set; }
    public int ActiveId { get; set; }
    public byte Default { get; set; }
    public SetEnum Ident { get; set; }
    public string Name { get; set; }
    public sbyte State { get; set; }
    public DateTime Date { get; set; }
}

.
This is how I serialize the object
public string Serialize(object serializeObject)
{
    MemoryStream stream = new MemoryStream();
    BinaryFormatter b = new BinaryFormatter();

    b.Serialize(stream, serializeObject);

    byte[] data = stream.ToArray();

    stream.Dispose();
    stream = new MemoryStream();

    using (ZipFile zip = new ZipFile())
    {
        zip.AddEntry("data", data);
        zip.Save(stream);
    }

    data = stream.ToArray();
    stream.Dispose();

    return Convert.ToBase64String(data);
}

In my first attempt I serialize the object, zip that content (about 1/3 smaller) and convert it to a base64 string. But base64 has a quite big overhead of 1/3 and I know there is base128 but I don't know how to start and my search for base128 encoding was unsuccessful.

Or is there any other way to do this?
And if not how is the best way to
this as base128?

Edit:
I tested the ObjectStateFormatter Class with the whole "Context" object which results in 8byte more and slower serialization/deserialization. Maybe I had to use it just on the properties instead of the whole class?

A:

Well, base128 is not that hard, if you know how base64 is done. The dutch wikipedia describes the process well (translated it for you):

Convert the data to binary.
Keep taking chunks of 7 bits (2^7 = 128)
Convert those 7 bits to an integer.
Look up that integer in a translation table that you defined and append the character found to the base128 string.

That translation table contains 128 compatible UTF8 characters, for example:
0: a
1: b
..
25: z
26: 0

The only requirement is that translation table is the same at both sender and reciever.

