This is the archived version of Roland Weigelt's weblog that ran from 2003 to 2023 at weblogs.asp.net

Convert GUIDs to a Shorter Textual Representation and Back

The shortest textual representation of a GUID available out-of-the-box is with ToString("N"), which will create a string of 32 characters, e.g.:

b91d07b8826e4233ba40142603cff7ef

If you have several GUIDs next to each other, e.g., in columns in an Excel file, they can take up a considerable amount of space. For my use case (Excel export/import of data from/to an application), hiding the columns was not an option, as I needed to be able to take a look at the GUIDs. Not for the actual value, just to notice differences and patterns in the data.

Behind the scenes, a GUID consists of 128 bits. Converting the bits to a (case-insensitive) hex number as done with ToString("N")  leaves some room for improvement. The usual choice for a better conversion from binary to text is base64 encoding, which is described in https://datatracker.ietf.org/doc/html/rfc4648#section-4. This encoding creates text that consists of case-sensitive letters, digits, and only a few special characters (more on that later).

The .NET framework offers the functions Convert.ToBase64String() and Convert.FromBase64String(), so implementing the conversion is straightforward.

Details worth noting

  • The result of Convert.ToBase64String(someGuid.ToByteArray()) is a string that always ends on two padding characters (“==”). These can be removed and added back later for a conversion into the other direction.
  • The base64 encoding uses the characters “+” and “/”. Depending on your scenario, this may cause issues, so replacing them with different characters is an option. In my case, I did not feel comfortable having arithmetic operators around in Excel, even though they do not cause trouble unless a cell value starts with “=”. This is why my code uses the characters “_” and “$” instead.

The code

I wrote a helper class with two functions and published it on https://github.com/RWeigelt/ShortGuidHelperDemo

The following code

var originalGuid = Guid.NewGuid();
Console.WriteLine($"From GUID   : {originalGuid:N}");

var shortId=ShortGuidHelper.GetShortId(originalGuid);
Console.WriteLine($"To short ID : {shortId}");

var recreatedGuid=ShortGuidHelper.GetGuid(shortId);
Console.WriteLine($"Back to GUID: {recreatedGuid:N}");

results in output similar to this:

From GUID   : b91d07b8826e4233ba40142603cff7ef
To short ID : uAcduW6CM0K6QBQmA8$37w
Back to GUID: b91d07b8826e4233ba40142603cff7ef

Ten characters saved for one GUID may not be much, but with several GUIDs next to each other, it still adds up.

6 Comments

  • You could also try ULIDs - https://github.com/ulid/spec

  • @Yuben: Thank you for the info! ULIDs are 26 characters (instead of 22 for the base64-encoded short ID presented here), but do not need any special characters and have other interesting properties.
    I'm wondering about the fact that the spec has a GPL 3.0 license, though. I'm not quite sure what this means in practice in this case. The C# implementation https://github.com/mcb2001/CSharp.Ulid has an MIT license.

  • this bring back memories :-)

    I wrote this 14 years ago https://stackoverflow.com/questions/1032376/guid-to-base64-for-url

  • @fredou: Looks like sooner or later everybody writes something like this ;-).

  • https://github.com/ullmark/hashids.net

  • @Iurii: Thank you for the link! I will keep the Hashid library in mind for use cases that do not involve encoding/decoding GUIDs. The GitHub page links to the homepage at https://hashids.org/net/ with some more info (nice: "the algorithm tries to avoid generating most common English curse words").
    Also interesting: "Who's Using Hashids" at https://github.com/hashids/hashids.github.io/wiki/Who's-Using-Hashids