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 wordsloading...
Last Post: vi-vim-cheat-sheet.jpg
Next Post: Simple and Fast Hash Functions in Delphi