Click here to Skip to main content
15,883,883 members
Articles / Programming Languages / C#
Tip/Trick

Reducing the string Length of a Guid

Rate me:
Please Sign up or sign in to vote.
4.95/5 (30 votes)
28 Mar 2018CPOL2 min read 91.2K   24   41
Need a unique identifier that is smaller than 36 characters? Represent a Guid in a 22 character string.

Introduction

The other day, we were sending some messages to services wherein a messageID was required. We used to create a messageID by using a Guid.NewGuid(), but the one of the receiving services threw an exception. It turned out that this one particular service defined the messageID to be only 30 characters or less. So what to do?

Some of us thought it would be a wise idea to use some form of timestamp in combination with a system identifier. Well, as you can imagine, in an environment that would produce a lot of messages, the chance of that messageID being unique drops dramatically. We wanted to stick with the Guid.

Okay, sticking with the Guid, maybe we can just remove the '-' and truncate the resulting string to 30 characters. Sure, that might work. Still, we are reducing the uniqueness. There must be a better way.

The Solution

We found that converting the Guid (16 bytes) to an ASCII representation using Base64 resulted in a useable and still unique messageID of only 22 characters.

C#
var newGuid = Guid.NewGuid();
var messageID = Convert.ToBase64String(newGuid.ToByteArray());

For example: The Guid 'e6248889-2a12-405a-b06d-9695b82c0a9c' (string length: 36) will get a Base64 representation: 'iYgk5hIqWkCwbZaVuCwKnA==' (string length: 24)

The Base64 representation ends with the '==' characters. You could just truncate these, without any impact on the uniqueness. Leaving you with an identifier of only 22 characters in length.

Proof

Just saying that this works might suffice, but here is a small piece of code that you can run that will prove that the Guid you convert can be converted back to the Guid you started with; ergo, the resulting string is as unique as the starting Guid.

C#
using System;

var newGuid = Guid.NewGuid();

Console.WriteLine($"GUID: {newGuid.ToString()}");
Console.WriteLine($"length: {newGuid.ToString().Length}" );

var base64 = Convert.ToBase64String(newGuid.ToByteArray());
Console.WriteLine($"Base64 representation: {base64}");
Console.WriteLine($"length: {base64.Length}" );

var reconstructedGuid = new Guid(Convert.FromBase64String(base64));
Console.WriteLine($"Restored GUID: {reconstructedGuid.ToString()}");
Console.WriteLine("Restore from Base64 : " + (reconstructedGuid==newGuid?"PASSED": "FAILED"));

Points of Interest

Please have a look at the blogpost Equipping our ASCII Armor by Jeff Atwood for more information on using a Guid in different forms. His blogpost inspired this tip.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) NoNerds
Netherlands Netherlands
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralRe: proof of uniqueness Pin
Middle Manager28-Mar-18 9:46
Middle Manager28-Mar-18 9:46 
GeneralRe: proof of uniqueness Pin
Christiaan van Bergen28-Mar-18 12:14
professionalChristiaan van Bergen28-Mar-18 12:14 
GeneralRe: proof of uniqueness Pin
Henrique C.30-Mar-18 2:48
professionalHenrique C.30-Mar-18 2:48 
GeneralRe: proof of uniqueness Pin
Middle Manager30-Mar-18 2:50
Middle Manager30-Mar-18 2:50 
GeneralRe: proof of uniqueness Pin
Thomas Johnson MCS30-Mar-18 9:19
Thomas Johnson MCS30-Mar-18 9:19 
GeneralRe: proof of uniqueness Pin
Christiaan van Bergen30-Mar-18 10:38
professionalChristiaan van Bergen30-Mar-18 10:38 
GeneralRe: proof of uniqueness Pin
Thomas Johnson MCS30-Mar-18 10:46
Thomas Johnson MCS30-Mar-18 10:46 
QuestionThanks Pin
John Bevan28-Mar-18 3:24
John Bevan28-Mar-18 3:24 
Nice tip; thanks for sharing.

FYI: If you needed to further reduce the number of characters this trick will shrink it down to 11 chars.

The trick works on the basis that there are 16 possibilities for each character in a GUID, so taking character pairs gives 256 (16 x 16) possibilities, so representing each pair as an ASCII character we could half the string's length (after excluding formatting characters such as hyphens and brackets), taking it from 32 characters to 16.

However, that's if we use ASCII; we have better options available; e.g. UTF-8. With that each code page can represent 65,536 (16 ^ 4) characters; so we could process our characters in quads to get down to 8 UTF-8 characters. However, we don't really want to use the first 32 control characters, and once we apply this offset that pushes us over the limit of the UTF-8 code page. So let's drop to triads (16 ^ 3 => 4096 possibilities). That means 10 triads plus an 11th pair; i.e. 11 UTF-8 characters.

Here's a PowerShell demo:

PowerShell
$InformationPreference = [System.Management.Automation.ActionPreference]::Continue

[string]$GuidJustTheDigits = ([Guid]::NewGuid().ToString() -replace '[{}-]','')
Write-Information "Just the digits length: $($GuidJustTheDigits.Length)" #32 chars
Write-Information "Just the digits: $GuidJustTheDigits" 

$CompressedGuid = ($GuidJustTheDigits -split '(.{3})' | ?{$_} | %{'0x{0}' -f $_} | %{32 + [int]$_} | %{[char]$_}) -join ''
Write-Information "Length of Compressed Guid: $($CompressedGuid.Length )" #11 chars
Write-Information "Compressed GUID: $CompressedGuid"

AnswerRe: Thanks Pin
Christiaan van Bergen28-Mar-18 12:09
professionalChristiaan van Bergen28-Mar-18 12:09 
AnswerRe: Thanks Pin
Fly Gheorghe30-Mar-18 3:18
Fly Gheorghe30-Mar-18 3:18 
GeneralRe: Thanks Pin
Christiaan van Bergen30-Mar-18 11:01
professionalChristiaan van Bergen30-Mar-18 11:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.