用户输入以创建用于生成随机数的种子

User's input to create Seed for Random Number generation

随机数生成器依赖于良好的种子来提供真正的随机数。好的种子的来源是接受用户的输入,因为人类行为是不确定的。

一种方法是让用户输入一些字符并测量击键之间的时间。这里有一些代码来说明这一点:

        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);
        }

我很想知道您对我的方法的看法和想法。有趣的是我从来没有在互联网上看到过这样的解决方案。

实际我觉得你对这些概念有点误解。

您正在注册伪随机数生成器。这些建立在生成随机数的函数之上,其中每个返回的数字都是根据前一个返回的数字计算得出的。知道第一个数字,您每次都会得到 完全 相同的序列。输出看起来是随机的,并且对于鬃毛目的来说是足够随机的。作为已知序列还可以为特定行为编写测试,因为您可以为每个测试 运行 重现 随机 数字。它基本上是一个已知的模式或数字序列。

但假设输出是加密安全的,随机性是不安全的。不要使用伪随机数生成秘密。不要使用伪随机数生成秘密。

大多数语言都有用于创建真实随机数的模块。 (在 .NET 中,它将是 CryptoRandomProvider)。这些 类 使用真正的熵,如网络包、鼠标和键盘输入、磁盘搜索等的组合来创建真正的随机数。在 Linux 上,您可以从 /dev/random 读取包含真正随机的字节,但也可能会耗尽。