You could use Base64:

string base64Guid = Convert.ToBase64String(Guid.NewGuid().ToByteArray());

That generates a string like E1HKfn68Pkms5zsZsvKONw==. Since a GUID is always 128 bits, you can omit the == that you know will always be present at the end and that will give you a 22 character string. This isn't as short as YouTube though.


As mentioned in the accepted answer, it can cause problems if you're using the GUID in the URL. Here is a more complete answer:

    public string ToShortString(Guid guid)
    {
        var base64Guid = Convert.ToBase64String(guid.ToByteArray());

        // Replace URL unfriendly characters with better ones
        base64Guid = base64Guid.Replace('+', '-').Replace('/', '_');

        // Remove the trailing ==
        return base64Guid.Substring(0, base64Guid.Length - 2);
    }

    public Guid FromShortString(string str)
    {
        str = str.Replace('_', '/').Replace('-', '+');
        var byteArray = Convert.FromBase64String(str + "==");
        return new Guid(byteArray);
    }

Usage:

        var guid = Guid.NewGuid();
        var shortStr = ToShortString(guid);
        // shortStr will look something like 2LP8GcHr-EC4D__QTizUWw
        var guid2 = FromShortString(shortStr);
        Assert.AreEqual(guid, guid2);

9 chars is not a GUID. Given that, you could use the hexadecimal representation of an int, which gives you a 8 char string.

You can use an id you might already have. Also you can use .GetHashCode against different simple types and there you have a different int. You can also xor different fields. And if you are into it, you might even use a Random number - hey, you have well above 2.000.000.000+ possible values if you stick to the positives ;)


It's not a GUID

Let me jump in with the following

It uses the TotalMilliseconds from EPOCH and a valid set of characters.

This will not be globally unique but unique to the instance where it's defines

public string YoutubeLikeId()
{
    Thread.Sleep(1);//make everything unique while looping
    long ticks = (long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1,0,0,0,0))).TotalMilliseconds;//EPOCH
    char[] baseChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".ToCharArray();
    
    int i = 32;
    char[] buffer = new char[i];
    int targetBase= baseChars.Length;

    do
    {
        buffer[--i] = baseChars[ticks % targetBase];
        ticks = ticks / targetBase;
    }
    while (ticks > 0);

    char[] result = new char[32 - i];
    Array.Copy(buffer, i, result, 0, 32 - i);

    return new string(result);
}

The output will come something like

XOTgBsu
XOTgBtB
XOTgBtR
XOTgBtg
XOTgBtw
XOTgBuE

Update: The same can be achieved from Guid as

var guid = Guid.NewGuid(); 
guid.ToString("N");
guid.ToString("N").Substring(0,8);
guid.ToString("N").Substring(8,4);
guid.ToString("N").Substring(12,4);
guid.ToString("N").Substring(16,4);
guid.ToString("N").Substring(20,12);

For a Guid ecd65132-ab5a-4587-87b8-b875e2fe0f35 it will break it down in chunks as ecd65132 ,ab5a , 4587,87b8,b875e2fe0f35

but i can't guarantee it to be unique always.

Update 2: There is also a project called ShortGuid to get a url friendly GUID it can be converted fron/to a regular Guid

It works by encoding the Guid to Base64 as the code below

public static string Encode(Guid guid)
{
    string encoded = Convert.ToBase64String(guid.ToByteArray());

    encoded = encoded
        .Replace("/", "_")
        .Replace("+", "-");
    return encoded.Substring(0, 22);
}

The good thing about it it can be decoded again to get the Guid back with

public static Guid Decode(string value)
{
    // avoid parsing larger strings/blobs
    if (value.Length != 22)
    {
        throw new ArgumentException("A ShortGuid must be exactly 22 characters long. Receive a character string.");
    }

    string base64 = value
        .Replace("_", "/")
        .Replace("-", "+") + "==";

    byte[] blob = Convert.FromBase64String(base64);
    var guid = new Guid(blob);

    var sanityCheck = Encode(guid);
    if (sanityCheck != value)
    {
        throw new FormatException(
            @"Invalid strict ShortGuid encoded string. The string '{value}' is valid URL-safe Base64, " +
            @"but failed a round-trip test expecting '{sanityCheck}'."
        );
    }

    return guid;
}

So a Guid 4039124b-6153-4721-84dc-f56f5b057ac2 will be encoded as SxI5QFNhIUeE3PVvWwV6wg and the Output will look something like.

ANf-MxRHHky2TptaXBxcwA
zpjp-stmVE6ZCbOjbeyzew
jk7P-XYFokmqgGguk_530A
81t6YZtkikGfLglibYkDhQ
qiM2GmqCK0e8wQvOSn-zLA

As others have mentioned, YouTube's VideoId is not technically a GUID since it's not inherently unique.

As per Wikipedia:

The total number of unique keys is 2128 or 3.4×1038. This number is so large that the probability of the same number being generated randomly twice is negligible.

The uniqueness YouTube's VideoId is maintained by their generator algorithm.

You can either write your own algorithm, or you can use some sort of random string generator and utilize the UNIQUE CONSTRAINT constraint in SQL to enforce its uniqueness.

First, create a UNIQUE CONSTRAINT in your database:

ALTER TABLE MyTable
ADD CONSTRAINT UniqueUrlId
UNIQUE (UrlId);

Then, for example, generate a random string (from philipproplesch's answer):

string shortUrl = System.Web.Security.Membership.GeneratePassword(11, 0);

If the generated UrlId is sufficiently random and sufficiently long you should rarely encounter the exception that is thrown when SQL encounters a duplicate UrlId. In such an event, you can easily handle the exception in your web app.