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.
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.
[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:
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:
new Random(Environment.TickCount & Int32.MaxValue);
–EOF (The Ultimate Computing & Technology Blog) —
Last Post: vi-vim-cheat-sheet.jpg
Next Post: Simple and Fast Hash Functions in Delphi