Generating Unique Keys in .Net


Introduction :

I have few applications where I need to create some unique IDs. GUIDs are great as they give Globally Unique identifier but they are big. I mean if you want to issue unique number in your application which you want to give as Booking Number or any reference number then GUIDs is obviously not a solution. Therefore, I need some simple Id which is unique too. For example when I send a request to my Credit Card Processor there’s an ID that correlates my invoice with the transaction at the provider. A GUID isn’t what I’d want here.

But one relatively simple solution is to create sequential ID which will be of appropriate size as well as it will guarantee uniqueness. Very Good and Simple solution!!! Isn’t it !! My answer would be NO !! Because it is security threat for your website. In case of Web Application where you can Retrieve your Order or Booking Details by just giving Order Reference number, you can easily BruteForce Sequential Reference numbers to retrieve records.

In this article I will discuss some of techniques.

Using DateTime and HashCode:

Using DateTime for generating unique keys is very common practice. I have remixed this approach by inducing HashCode in it also. Like

DateTime.Now.ToString().GetHashCode().ToString(“x”);

It will give you some key like 496bffe0. At the first glance it seems to be satisfied Unique key as its using current time and hashing to generate key but GetHashCode() doesn’t procduce unique code everytime. Althought Microsoft is using Double Hashing algorithms with N Number of collision resolving double hash function but during my experimentation I found lot of collisions.

Using GUIDs and HashCode:

So then I tried

Guid.NewGuid().ToString().GetHashCode().ToString(“x”);

It gives key something like 649cf2e3.Somehow I don’t think that this string representation at least is unique… 38 characters represented as 8? Ok 32 bits, but still it’s 8 digits and characters limited to hex values and yes my doubt got right as I wrote program which generated 100,000 keys and checked it for collisions and found several keys duplicated.

Using RNGCryptoServiceProvider and Character Masking :

The .net Framwork provides RNGCryptoServiceProvider class which Implements a cryptographic Random
Number Generator (RNG) using the implementation provided by the cryptographic service provider (CSP). This class is usually used to generate random numbers. Although I can use this class to generate unique number in some sense but it is also not collision less. Moreover while generating key we can make key more complicated by making it as alpha numeric rather than numeric only. So, I used this class along with some character masking to generate unique key of fixed length.

Below is code sample:

private string GetUniqueKey()
{
int maxSize  = 8 ;
int minSize = 5 ;
char[] chars = new char[62];
string a;
a = “abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890”;
chars = a.ToCharArray();
int size  = maxSize ;
byte[] data = new byte[1];
RNGCryptoServiceProvider  crypto = new RNGCryptoServiceProvider();
crypto.GetNonZeroBytes(data) ;
size =  maxSize ;
data = new byte[size];
crypto.GetNonZeroBytes(data);
StringBuilder result = new StringBuilder(size) ;
foreach(byte b in data )
{
result.Append(chars[b % (chars.Length – 1)]);
}
return result.ToString();
}

Analysis shows that RNGCrypto with Character Masking is best method to generate Unique keys.

Advertisements

7 thoughts on “Generating Unique Keys in .Net

  1. Hello
    I am studying in a university and i have a project to work on which i have a booking section using C#. what i am planning is if the user does the booking by entering their details i want to provide them a booking reference number which should be automatically generated by the system for their reference.
    i have the following pages on project
    Registeration page : the user needs to fill the details here.onces he click submit the page will be redirected to success.aspx over here i want to provide the user a reference number which later he can use to access his booking details

    Methods used
    i have created a class file and i am accessing the database through this class file. my database connections are working fine

    but what i want is
    once the user clicks the book button a reference number should be generated and it should also be inserted into the table in database along with the user details (i have created a coloumn named reference in the table too)

    Can u please provide a solution for the same
    It would be of great help

  2. I generated a collision (‘key already exists’) using this simple test harness.


    Hashtable ht = new Hashtable();
    for (int i = 0; i < 10000000; i++)
    {
    ht.Add(GetUniqueKey(),1);
    }
    Response.Write(GetUniqueKey());

    1. hi matthew ,

      i have already stated that :

      “Although I can use this class to generate unique number in some sense but it is also not collision less.”

      so it might be possible that collision occur by using this class also..but posibility are very less as compare to other two methods..

  3. I have generated 1 Crore unique values and stored in a Dictionary but not a single repetitive id.
    Thanks Dude for this code. Even if it generate a duplicate value, catch it in exception handler then generate next id.

  4. Hi Sandeep,

    Thanks for your code and analysis.
    I wanted to know what is the possibility that some one can predict next code being generated?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s