Keyvan Nayyeri

My daily musings about software and technology

Generating Random Strings in .NET

In a recent post I talked about random generation and some main aspects of it and some points that you need to consider when choosing a random generation method.

I also promised to write a future post about string random generation in .NET and give some methods to do it and also discuss about pros and cons of each method.

So here is that post that outlines some common methods and analyzes them.

GUID

GUID is a universally unique value and has a random value. There is a built-in support for GUID in almost all development platforms including .NET framework. To generate a random string value, you can simply generate a new GUID and use its ToString method to format the output.

GUID is a 128 bits data and what you see is just a string representation of it. You have to know that this string representation isn't case sensitive.

By default, a GUID value in .NET has dash characters but you can format it to strip out these characters. There are different formats for GUID that you can use just by passing a single string value to ToString method of Guid class. These values may be D, P, B and N but only the latter format strips dashes.

Below code is a very simple method that generates such a string value and returns it.

public static string GuidMethod()

{

    Guid guid = Guid.NewGuid();

    return guid.ToString("N");

}

Output

Each method has some pros and cons. GUID is a good way to generate unique values. With GUID you can have a universally unique value. moreover, it's the easiest way and you see that I generates a value in two lines of code (even though it was possible to do that in a single line but I wanted a more readable code).

Beside these, GUID can't generate different lengths of values. Your output has a fixed length which is usually longer than our expectations. A GUID consists of some components and you may think that you can remove some of these components to have shorter strings but this breaks the uniqueness of GUID.

On the other hand, GUID generates strings with a limited set of alphanumerical characters and you have no control on this.

However, GUID is a suitable method for many cases.

Random Numbers and ASCII Codes

The second method that most likely has come to your mind at the first glance is using the string representation of randomly generated numbers with their ASCII codes. This is true and you can do that.

The idea and implementation is very simple so I just show the code.

public static string RandomNumbersMethod(int length)

{

    string result = string.Empty;

 

    Random random = new Random();

    for (int i = 0; i < length; i++)

    {

        char ch = Convert.ToChar(random.Next(97, 122));

        result += ch;

    }

 

    return result;

}

Output

This method is more customizable than GUID. Of course, it doesn't generate unique values at all so isn't suitable for scenarios where you need to have unique values.

But this method can generate different length of strings (as you see) and also can generate different characters. You can simply tweak above code to use more ranges of character numbers.

This is a very simple and common method. If uniqueness isn't important for you, this is the best choice.

Hashing and GetHashCode Method

Methods that work based on hashing and GetHashCode method of objects are different and there are various inspirations for this basic idea.

The main idea is using some type of hashing mechanism to convert a number or string to a hashed string. So usually you have to apply one of the abovementioned methods to generate a random string (or even a random number) then get its hash equivalent to be unique.

For example, in the below code I get a GUID value and generate its hash value.

public static string HashingWithGuidMethod()

{

    Guid guid = Guid.NewGuid();

    return guid.GetHashCode().ToString("x");

}

Output

As you see, this method generated a very shorter value for a GUID which is a plus point for it.

One of the other ways to use hashing technique is generating a random number and finding its hash code.

public static string HashingWithNumbersMethod(int length)

{

    int upperBound = Convert.ToInt32((Math.Pow(10, (double)length)) - 1);

 

    Random random = new Random();

    int number = random.Next(0, upperBound);

 

    return number.GetHashCode().ToString("x");

}

Output

This generated another value from the hash code of an integer number of a specified length. This latter implementation was more customizable because I could change the length.

But all these hashing methods have some limitations. The first limitation is their uniqueness because they can't generate unique values. The second limitation is your control over the length in some cases. Sometimes you may get different lengths for your results. However, one of the best applications for this method, as you see, is the ability to convert a longer generated string to a shorter one like what I did with GUID.

Date and Time

One of the common techniques for generating unique (or almost unique) values in an application is applying date and time in your string values somehow. There would be various implementations based on this idea but we use date and time as a unique parameter to generate our strings.

For instance, I can use the binary form of current date and time to generate its string value and then use its hash code as a random string.

public static string DateAndTimeMethod()

{

    long ticks = DateTime.Now.ToBinary();

 

    return ticks.GetHashCode().ToString("x");

}

Output

Here there are some points. You can write several implementations based on the main idea of using date and time values. The uniqueness of your result is tight to the number of date and time parameters that you apply to generate your result. If you use all elements of current date and time then you have a unique value. Of course, this has its effect on the length of the result, though.

This method can provide unique (or almost unique) values for you but is a little harder to work with.

RNGCryptoServiceProvider

The last method that I cover is my favorite one! There is an RNGCryptoServiceProvider class in .NET framework which is mainly designed for cryptography and security purposes to generate random numbers and is suitable to generate unique strings with different lengths and desire characters so this is an excellent choice!

This provider gets a string that includes all the characters that we like to have in the generated string as well as a length then generates all possible values for you. The built-in working mechanism guarantees the uniqueness because it finds all the permutations of your characters. As soon as you give a wider range of characters or longer length, it can provide more results. By the way, I originally found this method on this CodeProject article.

public static string RNGCryptoServiceProviderMethod(int length)

{

    string charsToUse = "abcdefghijklmnopqrstuvwxyz1234567890";

 

    char[] chars = charsToUse.ToCharArray();

    int size = length;

 

    byte[] data = new byte[1];

    RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();

    crypto.GetNonZeroBytes(data);

    size = length;

 

    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();

}

Outut

This method is able to generate unique values. It also can generate strings with different lengths and from a desire set of characters.

These are some methods that I could mention but there would be much more methods that use completely different approaches or develop these ideas to be better.

You can download the sample source code for this post from here.

9 Comments

Marc Brooks
Apr 04, 2008 11:52 AM
#

If you intend to have users enter those strings, please make your charsToUse NOT include I, 1, O, 0, 2 and Z to help avoid mistakes.


Hank Lynch
Apr 04, 2008 11:53 AM
#

Wow, sweet timing. I was just gonna write a tiny url redirector tonight and was thinking about how I was gonna gen up my strings. And here it is, thanks dude.


Marc Brooks
Apr 04, 2008 11:55 AM
#

Also, the char array allocated in this line:

char[] chars = new char[62];

Is completely discarded in this line:

chars = charsToUse.ToCharArray();

Which is why I've always preferred initializing declarations... delete the first line and make the second one:

char[] chars = charsToUse.ToCharArray();

This also avoids possible confusion about the size of the chars array since it's GOING TO BE the size of that returned by the ToCharArray() method... period.


Keyvan Nayyeri
Apr 04, 2008 12:05 PM
#

@Marc Brooks,

Thank you, good catch :-) I updated the code.

@Hank Lynch:

Interesting :-)


Steve
Apr 05, 2008 4:13 AM
#

IIRC, GetHashCode on System.Int32 just returns itself ;)


Keyvan Nayyeri
Apr 05, 2008 11:21 AM
#

@Steve:

Yes, you're absolutely right. I didn't attend to the point at all. I had to generate a string from the integer then get its hash code.

Thanks for the point :-)


Puja
Aug 30, 2008 10:14 AM
#

how to decrypt ,i mean get the original value?


Kaveh
Nov 10, 2008 3:39 AM
#

What about System.IO.Path.GetRandomFileName ().Replace(".", "")?

I think it is good enough for this purpose and we can use sub-strings of it or combine 2 of it to get the string we want.

Ofcourse your approach is much better yet ... (being lazy!)


Nicolas
May 14, 2010 10:13 AM
#
Great article. Tahnks!

Leave a Comment