BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

.NET Framework
.NET 1.1+

Creating Globally Unique Identifiers (GUIDs) in .NET

It is important in many business systems that items are marked with a unique reference. Often this is a sequential number generated by a database or a code entered by a user. In some situations, these options are not enough so GUIDs may be employed.

Unique Identifiers

When storing data, either in a database or other storage medium, it is usual to assign an identifying value or key against each item held. There are many ways in which to generate such a key. In an accounting system, the ID for each customer may be entered by the user or generated from other data using a standard that is easy to remember. In this case, the software will perform a validation check to ensure no duplication. In other systems a sequential series of numbers may be used to ensure that the keys remain unique.

These methods, and many others, are useful when all users have access to the data at all times. However, many applications are now becoming disconnected with mobile users taking copies of the data on their notebooks or PDAs. When these users add new information to their local copy of the data they have no database connectivity and therefore no way of knowing which IDs have already been allocated.

The GUID

The Globally Unique Identifier (GUID), is based upon the Universally Unique Identifier (UUID) standard. GUIDs are 128-bit numbers that are usually written as thirty-two hexadecimal digits grouped into five sections. The following is an example GUID:

8599AE31-2409-4875-9ECF-0698FAE23EDA

Most of the digits in the GUID are used for the unique identifier itself with several bits storing information about the GUID. For example, the number four in the third group of the example GUID shows that the value was generated using a version 4 algorithm. The number of bits used means that the number of possible GUIDs is huge.

The structure and scale of the GUID means that new unique IDs can be generated with a remarkably small chance of anybody in the world ever creating a duplicate value. When their use is restricted to a single software application, the risk of duplication within the application is even smaller. This makes them ideal for the production of unique keys in disconnected scenarios as it can be assumed that there will be no duplication of keys during synchronisation. This is demonstrated in Microsoft's SQL Server database replication. Each replicated table row is assigned a GUID, which is the unique identifier used across all of the databases being synchronised.

The Guid Structure

Globally Unique Identifiers can be generated using the .NET framework's Guid structure within the System namespace. Note that this is a structure, not a class, so is a value type. This also means that Guids cannot be assigned a null value.

Guid Constructors

The Guid structure provides six constructors, each allowing the new GUID to be assigned a value. Three of these will be demonstrated in this article. The constructors are used when a specific value is required. The simplest constructor requires no parameters as it generates a new GUID value containing only zeroes:

Guid id = new Guid();
Console.WriteLine(id);          // Outputs "00000000-0000-0000-0000-000000000000"

If the value of a GUID is known and is held in a string, a second constructor can be used that converts the string into a Guid. The string is passed as the only parameter:

Guid id = new Guid("8599AE31-2409-4875-9ECF-0698FAE23EDA");
Console.WriteLine(id);          // Outputs "8599ae31-2409-4875-9ecf-0698fae23eda"

The third constructor to be considered in this article allows every byte of the new Guid to be specified individually from an array of bytes. This constructor reveals more of the internal structure of the Guid when it is outputted. Note when running the following example that the first three groups of bytes are reversed. This is because these groups are stored as a 32-bit integer and two 16-bit integers that are outputted with the least significant bytes first. The remaining two groups are simply eight individual bytes so their order is the same as that used in the constructor.

byte[] bytes = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

Guid id = new Guid(bytes);
Console.WriteLine(id);          // Outputs "03020100-0504-0706-0809-0a0b0c0d0e0f"

Generating New Guids

The Guid constructors are useful when a specific GUID value is required. However, when new objects are created and require a new unique identifier, a new Guid value must be generated. This is achieved using the static NewGuid method, as demonstrated by the following example. NB: The GUID generated will not match the one shown in the sample code.

Guid id = Guid.NewGuid();
Console.WriteLine(id);          // Outputs "8c1d1c4b-df68-454c-bf30-953e5701949f"

Empty Guids

As the Guid structure cannot be set to null, a value must be used to represent an ID that is not set. This value, known as the empty GUID, consists only of zeroes. This is the same value that is generated by the parameter-less constructor. In order that a new Guid structure is not created every time a value must be compared with the empty GUID, the structure provides the Empty property. This property is read-only and always returns an empty GUID.

Guid id = Guid.NewGuid();
Guid id2 = new Guid();

Console.WriteLine(id == Guid.Empty);    // Outputs "False"
Console.WriteLine(id2 == Guid.Empty);   // Outputs "True"

Console.WriteLine(Guid.Empty);  // Outputs "00000000-0000-0000-0000-000000000000"

Formatting Guids as Strings

As with all objects and structures, the Guid can be converted to a string using the ToString method. If the method is used without parameters, the Guid is formatted as a simple series of hexadecimal digits in the five groups described earlier.

string s = Guid.Empty.ToString();
Console.WriteLine(s);           // Outputs "00000000-0000-0000-0000-000000000000"

The format of the converted string can be modified using a format specifier. This is passed as a string parameter to the ToString method. The four available format specifiers are listed in the table below.

SpecifierDescriptionExamples
DDefault format of thirty-two digits with groups separated by hyphens."00000000-0000-0000-0000-000000000000"
NA series of thirty-two hexadecimal digits with no separators between groups."00000000000000000000000000000000"
BDefault format surrounded by brackets."{00000000-0000-0000-0000-000000000000}"
PDefault format surrounded by parentheses."(00000000-0000-0000-0000-000000000000)"

These formats can be demonstrated by executing the following sample code:

Console.WriteLine(Guid.Empty.ToString("D"));
Console.WriteLine(Guid.Empty.ToString("N"));
Console.WriteLine(Guid.Empty.ToString("B"));
Console.WriteLine(Guid.Empty.ToString("P"));

/* OUTPUT

00000000-0000-0000-0000-000000000000
00000000000000000000000000000000
{00000000-0000-0000-0000-000000000000}
(00000000-0000-0000-0000-000000000000)

*/
2 December 2007