Short GUID

kick it on DotNetKicks.com

If you've used Guid.NewGuid().ToString(), you've probably seen a GUID like this:

AAD5E2E7-AD78-487a-9B37-458B9F1EE897

That may suite your purposes, but if you're case-sensitive, you can actually get a shortened version of the same GUID. Here's how:

string shortGuid = Convert.ToBase64String(Guid.NewGuid().ToByteArray())
            .Substring(0, 22)
            .Replace("/", "_")
            .Replace("+", "-");

The output:

b14I850fIE6cuyv7VnP6WA

Or, as an extension method:

public static class GuidExtensions
{
    /// <summary>Get a 22-character, case-sensitive GUID as a string.</summary>
    public static string ToShortString(this Guid guid)
    {
        return Convert.ToBase64String(guid.ToByteArray())
            .Substring(0, 22)
            .Replace("/", "_")
            .Replace("+", "-");
    }
}

Used like:

string shortGuid = Guid.NewGuid().ToShortString();

That's 32 characters vs. 22. Nothing magical happens here: Substring(0, 22) cuts off two trailing == characters that always appear, then the GUID is made URI and filename friendly by replacing / and +.

Hope this helps if you're looking for a shorter global identifier!

Update: 11/16/09

zm asked how this could be converted back to a valid Guid. If you'd like to do that, it's best to create a class out of this "short GUID" idea. Using the ShortGuid class at the end of this post, you can do that.

With ShortGuid, to get a short, 22-character GUID:

string shortGuid = new ShortGuid(Guid.NewGuid());

To convert that short GUID back into a Guid:

Guid regularGuid = ShortGuid.Parse(shortGuid);

When you compare that they are equal, it's true:

Guid regularGuid = Guid.NewGuid();
string shortGuid = new ShortGuid(regularGuid);
 
// Writes "True"
Console.WriteLine(regularGuid == ShortGuid.Parse(shortGuid));

Here's the ShortGuid class that makes this magic happen:

public class ShortGuid
{
    private readonly Guid guid;
    private readonly string value;
 
    /// <summary>Create a 22-character case-sensitive short GUID.</summary>
    public ShortGuid(Guid guid)
    {
        if (guid == null)
        {
            throw new ArgumentNullException("guid");
        }
 
        this.guid = guid;
        this.value = Convert.ToBase64String(guid.ToByteArray())
            .Substring(0, 22)
            .Replace("/", "_")
            .Replace("+", "-");
    }
 
    /// <summary>Get the short GUID as a string.</summary>
    public override string ToString()
    {
        return this.value;
    }
 
    /// <summary>Get the Guid object from which the short GUID was created.</summary>
    public Guid ToGuid()
    {
        return this.guid;
    }
 
    /// <summary>Get a short GUID as a Guid object.</summary>
    /// <exception cref="System.ArgumentNullException"></exception>
    /// <exception cref="System.FormatException"></exception>
    public static ShortGuid Parse(string shortGuid)
    {
        if (shortGuid == null)
        {
            throw new ArgumentNullException("shortGuid");
        }
        else if (shortGuid.Length != 22)
        {
            throw new FormatException("Input string was not in a correct format.");
        }
 
        return new ShortGuid(new Guid(Convert.FromBase64String
            (shortGuid.Replace("_", "/").Replace("-", "+") + "==")));
    }
 
    public static implicit operator String(ShortGuid guid)
    {
        return guid.ToString();
    }
 
    public static implicit operator Guid(ShortGuid shortGuid)
    {
        return shortGuid.guid;
    }
}

kick it on DotNetKicks.com

2 Responses to “Short GUID”

  1. zm Says:
    November 16th, 2009 at 1:45 pm

    How about converting your short guid back to a valid 32bit guid ?

  2. Marc Schubert Says:
    November 26th, 2009 at 4:15 pm

    Why you convert the Guid in to a “ShortGuid” ?
    I think the Hex-Presentation is a good way to do this.

    In a project i’ve been involved as Software Developer and Consultant we used the Guid.ToByteArray() to store the Guid as a RAW 16 representation in Oracle-DB.

    The implementation of ToByteArray; there is a bitshifting. The Hex-representation are not longer the same to the “string-guid”. If you are only in the .NET-Context, that will not be a problem. If you got issues with converting, feel free to contact me, i can give you some solutions to solve the problem. (ms.int[at']online.de).

    Regards,

    Marc

Leave a Reply

To include code, use <pre lang="csharp">// code...</pre>, where "csharp" is any language (e.g. "javascript", "html", "xml", etc).