在单例中种子Random()的最佳方法

我在单例类中有一个需要使用.NET系统的方法。 Random() ,因为在multithreading环境中调用该方法,我不能只创建一次并静态声明它,但每次调用该方法时我都必须创建一个Random()对象。 由于Random()默认种子基于时钟滴答,因此在我的senario中它不够随机。 为了创造一个更好的种子,我已经研究了几种方法并且认为以下一种方法是最好的,但可能还有其他(更快/更好)的方法来做我想知道的。

 Random rnd = new Random(BitConverter.ToInt32(Guid.NewGuid().ToByteArray(), 0)); 

不要试图自己想出更好的种子,而是使用System.Security.Cryptography.RandomNumberGenerator 。

它使用基于复杂算法的种子,该算法涉及许多不同的环境变量。 系统时间就是其中之一,因为IIRC是你的网卡的MAC地址等。

它也被认为是比Random类实现的算法更“随机”的算法。

这是我的实施。 线程安全,无锁定。

 public static class StrongRandom { [ThreadStatic] private static Random _random; public static int Next(int inclusiveLowerBound, int inclusiveUpperBound) { if (_random == null) { var cryptoResult = new byte[4]; new RNGCryptoServiceProvider().GetBytes(cryptoResult); int seed = BitConverter.ToInt32(cryptoResult, 0); _random = new Random(seed); } // upper bound of Random.Next is exclusive int exclusiveUpperBound = inclusiveUpperBound + 1; return _random.Next(inclusiveLowerBound, exclusiveUpperBound); } } 

静态创建它并使用锁来使其线程安全:

 public static class RandomProvider { private static Random _rnd = new Random(); private static object _sync = new object(); public static int Next() { lock (_sync) { return _rnd.Next(); } } public static int Next(int max) { lock (_sync) { return _rnd.Next(max); } } public static int Next(int min, int max) { lock (_sync) { return _rnd.Next(min, max); } } } 

如果由于某种原因在每个线程中仍然需要Random对象,则可以使用静态类来为它们设定种子:

 Random r = new Random(RandomProvider.Next() ^ Environment.TickCount); 

使用RNGCryptoServiceProvider生成随机数的示例程序

 class Program { public static void Main(string[] args) { int i; byte bRandom; String sL; for (i = 0; i < 10; i++) { bRandom = GetRandom(); sL = string.Format("Random Number: {0}", bRandom); Console.WriteLine(sL); } Console.ReadLine(); } public static byte GetRandom() { RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); // Create a byte array to hold the random value. byte[] randomNumber = new byte[1]; rngCsp.GetBytes(randomNumber); return randomNumber[0]; } }