programming and human factors

06 Oct 2005

Equipping our ASCII Armor

On one of our e-commerce web sites, we needed a unique transaction ID to pass to a third party reporting tool on the checkout pages. We already had a GUID on the page for internal use. And you know how much we love GUIDs!

22da5537-de54-459d-9b33-f40f2101143b

A GUID is 128 bits, or 16 bytes. And the third party can accept 20 bytes.

This seems workable until you realize that those 20 bytes have to be represented as a plain text string to be transmitted via HTTP in a form post or querystring.

So the question is, how do we represent a 128-bit integer in a plain text string that fits in 20 characters? In other words, we need to equip our ASCII Armor.

There's a Guid.ToByteArray() method which returns an array of 16 bytes (0-255). So we could just use ASCII values 0-255 to represent each byte, right? But wait a minute. ASCII 13 is carriage return! And good luck sending ASCII 0 (aka null) to anyone. Hmm.

We're forced to use only printable ASCII characters. Which means we'll have to use more bytes to represent the same data; it's unavoidable. Let's experiment with a few forms of ASCII armor and see how close we can get.

A Hex encoded GUID..

Dim g As Guid = Guid.NewGuid
Dim sb As New Text.StringBuilder
For Each b As Byte In g.ToByteArray
sb.Append(String.Format("{0:X2}", b))
Next
Console.WriteLine(sb.ToString)