随机数生成器依赖于良好的种子以提供真实的随机数。关于良好种子的来源是接受用户的输入,因为人类行为不是确定性的。
一种方法是让用户输入一些字符并测量击键之间的时间。这里有一些代码来说明这一点:
Console.WriteLine("please enter some text (at least 10 characters)");
DateTime startDateTime = DateTime.Now;
List<double> timeStamps = new List<double>();
ConsoleKeyInfo cki;
int cnt = 0;
do
{
cki = Console.ReadKey();
double timeStamp = DateTime.Now.Subtract(startDateTime).TotalMilliseconds;
timeStamps.Add(timeStamp);
cnt++;
}
while ( (cki.Key != ConsoleKey.Enter) || (cnt<3) );
Console.WriteLine();
上面的代码测量密钥库之间的时间,密钥库存储在数组 timeStamps 中。
使用此人类数据,计算这样的种子:
double sum = timeStamps.Sum(v => v * 20);
int seed = Convert.ToInt32(sum);
Console.WriteLine($"seed: {seed}");
然后我们可以计算实际随机数:
Console.WriteLine("5 random values:");
Random rnd = new Random(seed);
for(int i=0;i<5;i++)
{
int n = rnd.Next(100, 200);
Console.WriteLine(n);
}
我对你的观点以及你对我的方法的看法感兴趣。有趣的是,我从来没有在互联网上看到这样的解决方案。
答案 0 :(得分:-1)
实际上我觉得你有点误解了这些概念。
您正在重复使用伪随机数生成器。它们建立在产生随机数的函数之上,其中返回的每个数字都是根据返回的前一个数字计算的。知道第一个数字,每次都得到精确相同的序列。输出看起来是随机的,并且足够随机用于鬃毛目的。作为已知序列还可以为特定行为编写测试,因为您可以为每次测试运行重现随机数字。它基本上是一种已知的模式或数字序列。
但假设输出是加密安全的随机性并不安全。不要使用伪随机数生成秘密。不要使用伪随机数生成秘密。
大多数语言都有用于创建真实随机数的模块。 (在.NET中它将是CryptoRandomProvider)。这些类使用真正的熵,如网络包的组合,鼠标和键盘上的输入,磁盘搜索以及创建真正随机数的东西。在Linux上,您可以从/ dev / random读取包含真正随机字节的内容,但也可能会耗尽。