参考 《C# 6.0 in a Nutshell》

使用同一种子生成的随机数一样

  1. Random r1 = new Random (1);
  2. Random r2 = new Random (0);
  3. Console.WriteLine (r1.Next (100) + ", " + r1.Next (100)); // 24, 11
  4. Console.WriteLine (r2.Next (100) + ", " + r2.Next (100)); // 24, 11

默认使用系统时钟作为种子

这也导致下面代码中 r3 和 r4 的创建时间间隔过短,种子一样,生成的随机数也一样。

  1. Random r3 = new Random();
  2. Random r4 = new Random();
  3. Console.WriteLine (r3.Next (100) + ", " + r3.Next (100)); // x, y
  4. Console.WriteLine (r4.Next (100) + ", " + r4.Next (100)); // x, y

只要在 r3 和 r4 的创建过程中间隔一些耗时较长的操作就可以保证种子不一样,但这样做太麻烦了,我们用的更多的是下面的方案。

使用 Guid 作为种子

  1. Random r5 = new Random (Guid.NewGuid().GetHashCode());
  2. Random r6 = new Random (Guid.NewGuid().GetHashCode());
  3. Console.WriteLine (r5.Next (100) + ", " + r5.Next (100)); // a, b
  4. Console.WriteLine (r6.Next (100) + ", " + r6.Next (100)); // c, d

真随机数

Random 生成的随机数并不是真随机数,,NET 内置了 RandomNumberGenerator 用于生成真随机数。

  1. var rand = System.Security.Cryptography.RandomNumberGenerator.Create();
  2. byte[] bytes = new byte [4];
  3. rand.GetBytes (bytes); // Fill the byte array with random numbers.
  4. BitConverter.ToInt32 (bytes, 0).Dump ("A cryptographically strong random integer");

PS:RandomNumberGenerator vs RNGCryptoServiceProvider