C# Randomness Using GUID


I have a C# function that generates a random upper case string of given length. It looks straightforward and the class StringBuilder is used to concatenate each random character.

1
2
3
4
5
6
7
8
9
10
public static string GenerateRandomString(int strlen)
{
    var builder = new StringBuilder();
    var random = new Random();
    for (int i = 0; i < strlen; i++)
    {
        builder.Append((char)(65 + random.Next(26)));
    }
    return builder.ToString();
}
public static string GenerateRandomString(int strlen)
{
    var builder = new StringBuilder();
    var random = new Random();
    for (int i = 0; i < strlen; i++)
    {
        builder.Append((char)(65 + random.Next(26)));
    }
    return builder.ToString();
}

However, when I write a unit test that tests the randomness of the produced string, it failed more often than I expected.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[TestMethod]
public void TestGenerateRandomString()
{
    var hash = new HashSet<string>();
    for (int i = 0; i < 100; i++)
    {
        var len = 500;
        var s = MathUtils.GenerateRandomString(len);
        if (hash.Contains(s))
        {
            Assert.Fail(s); // random string should not appear before
        }
        else
        {
            hash.Add(s);    
        }                
    }
}
[TestMethod]
public void TestGenerateRandomString()
{
    var hash = new HashSet<string>();
    for (int i = 0; i < 100; i++)
    {
        var len = 500;
        var s = MathUtils.GenerateRandomString(len);
        if (hash.Contains(s))
        {
            Assert.Fail(s); // random string should not appear before
        }
        else
        {
            hash.Add(s);    
        }                
    }
}

It looks like that by default, the constructor for class Random() takes a default seed, which isn’t good enough. We can replace with the following:

1
var random = new Random(Guid.NewGuid().GetHashCode());
var random = new Random(Guid.NewGuid().GetHashCode());

Using Guid.NewGuid() ensures uniqueness but not randomness. Based on the hash code, a good randomness is achieved.

on another note, using TickCount can be also a good seed:

1
new Random(Environment.TickCount & Int32.MaxValue);
new Random(Environment.TickCount & Int32.MaxValue);

–EOF (The Ultimate Computing & Technology Blog) —

GD Star Rating
loading...
290 words
Last Post: vi-vim-cheat-sheet.jpg
Next Post: Simple and Fast Hash Functions in Delphi

The Permanent URL is: C# Randomness Using GUID

Leave a Reply