Click here to Skip to main content
15,881,424 members
Articles / Programming Languages / PHP
Tip/Trick

ShortGUID

Rate me:
Please Sign up or sign in to vote.
4.75/5 (4 votes)
30 Apr 2012CPOL1 min read 38.4K   10   7
A set of functions to get slightly shorter unique Guids

Introduction

Here is a set of functions to shorten GUIDs in C# and PHP.

It is a reversible algorithm that transform a guid of 36 characters to 22 characters.
 

Background

GUIDs are a very useful tool for your web and application developers, but a little bit verbose.

The small function below lets you shave 30% off the guid string size while keeping the entire data.

This is not rocket science, I use the standard: Base64 with URL and Filename Safe Alphabet (RFC 4648 'base64url' encoding) without the end padding.

How does it work.

A normal guid uses the characters '0' to '9', 'A' to 'F'. This is a range of 16 different characters. It also have generally 4 dashes that contain no data.

  • A standard guid contains 128 bits of data and is generally displayed as string  of length 36.

Fortunately, we can use more characters.

This algorithm uses the characters '0' to '9', 'a' to 'z', 'A' to 'Z' and also '-' et '_'. This is a range of 64 characters.

Using a range of 64 different characters, to store 128 bits we only need a string of length 22.

Therefore a shortGuid is 22 characters long

Using the Code

The ToShortString method produces a short string like this one: U1ZBOzMa-0eV_4gFv965cQ

C#
String shortString = someGuid.ToShortString();

Then the ParseShortGuid:

C#
Guid parsedGuid =  ParseShortGuid("U1ZBOzMa-0eV_4gFv965cQ"); 

The Main C# Functions

C#
private static string ToShortGuid(this Guid newGuid)
{
    string modifiedBase64 = Convert.ToBase64String(newGuid.ToByteArray())
        .Replace('+', '-').Replace('/', '_') // avoid invalid URL characters
        .Substring(0, 22);
    return modifiedBase64;
}

private static Guid ParseShortGuid(string shortGuid)
{
    string base64 = shortGuid.Replace('-', '+').Replace('_', '/') + "==";
    Byte[] bytes = Convert.FromBase64String(base64);
    return new Guid(bytes);
} 

The Main PHP Functions

These are the equivalent functions in PHP.

PHP
function ParseShortGuid($a)
{
   $a=str_replace('_','/',str_replace('-','+',$a))."==";
   $a=base64_decode($a);
   if ($a==false || strlen($a)<16) return NULL;
   $a= bin2hex($a);
   $a = substr($a,6,2).substr($a,4,2).substr($a,2,2).substr($a,0,2)
      .'-'.substr($a,10,2).substr($a,8,2)
      .'-'.substr($a,14,2).substr($a,12,2)
      .'-'.substr($a,16,4)
      .'-'.substr($a,20,12);
   return $a;
}    

ToShortGuid uses the hex2bin function if you have a recent PHP but will fallback if it is not available.

PHP
function ToShortGuid($a)
{
   $a=str_replace('-','',str_replace('{','',str_replace('}','',$a)));
   $a = substr($a,6,2).substr($a,4,2).substr($a,2,2).substr($a,0,2)
     .substr($a,10,2).substr($a,8,2)
     .substr($a,14,2).substr($a,12,2)
     .substr($a,16,4)
     .substr($a,20,12);
   if(function_exists('hex2bin')) $a= hex2bin($a);
   else
   {
      $bin = '';
      for ($i = 0; $i < strlen($a); $i += 2) {
        $bin .= chr(hexdec($a{$i}.$a{($i + 1)}));
      }
      $a = $bin;
   }
   $a=base64_encode($a);
   $a=str_replace('/','_',str_replace('+','-',$a));
   $a=substr($a,0,22);
   return $a;
}      

Points of Interest

It would be nice to post other languages.

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)
France France
I am a French programmer.
These days I spend most of my time with the .NET framework, JavaScript and html.

Comments and Discussions

 
QuestionCan i use it as identifier. Pin
Member 1033717910-Feb-14 8:23
Member 1033717910-Feb-14 8:23 
AnswerRe: Can i use it as identifier. Pin
PIEBALDconsult10-Feb-14 8:53
mvePIEBALDconsult10-Feb-14 8:53 
QuestionHow? Pin
Corey Fournier30-Apr-12 18:08
Corey Fournier30-Apr-12 18:08 
AnswerRe: How? Pin
Pascal Ganaye1-May-12 10:44
Pascal Ganaye1-May-12 10:44 
QuestionFormatting Pin
Mehdi Gholam26-Apr-12 4:32
Mehdi Gholam26-Apr-12 4:32 
AnswerRe: Formatting Pin
Pascal Ganaye26-Apr-12 5:27
Pascal Ganaye26-Apr-12 5:27 
GeneralRe: Formatting Pin
richard norris21-Aug-15 4:26
richard norris21-Aug-15 4:26 
I know this is old, but although I agree:

If you want people to type it, I say you're right let stick to guids.
But in other scenarios, where size matters more then it make sense.


I believe your example usage (creating session IDs) is a terrible misuse of your algorithm, and if used in such ways would introduce a subtle security vulnerability for web applications. The reason for this is the fact that although GUIDs are great at being unique they are not great at being non-deterministic (low entropy), they were not designed for cryptographic use.

Secure session IDs although need to be unique have to be as non-deterministic as possible to be safe to use. Take into account that a malicious hacker could hijack someone's session if these IDs were guessed, well in this case worked out.

See this thread:
[How Deterministic Are Net GUIDS]

Look how a GUID is structured by reading how a GUID is created on Wikipedia: [Globally Unique Identifier]

Do a bit more research. A cryptographically secure random number generator would be a better choice, these API's exist without the use of hardware generators too. If you do use GUIDs you would require a second token that had high entropy to support it.

Edit: In .NET you can use the RNGCryptoServiceProvider class to help achieve this, check this thread out it contains an example although the question is about thread safety: [Is the use of rngcryptoserviceprovider in asp.net sessionid threadsafe]
Richard Norris (NozFX)


modified 21-Aug-15 10:36am.

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.