BlackWaspTM
.NET Framework
.NET 1.1+

Creating Globally Unique Identifiers (GUIDs) in .NET

by Richard Carr, published at http://www.blackwasp.co.uk/Guids.aspx

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"
2 December 2007