.NET框架:随机数发生器产生重复模式 [英] .NET Framework: Random number generator produces repeating pattern

查看:217
本文介绍了.NET框架:随机数发生器产生重复模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:这不是重复,这不是如何使用一个随机数发生器一个天真的误解造成的。谢谢你。

我似乎已经发现了由System.Random类生成的数字的重复模式。我使用的是主随机实例产生第二个主随机实例的种子。通过此主随机实例产生的值显示出的重复图案。特别是,所产生的第三个数字是非常predictable。

I seem to have discovered a repeating pattern in the numbers generated by the System.Random class. I am using a "master" Random instance to generate a seed for a second "main" Random instance. The values produced by this main Random instance exhibit a repeating pattern. In particular, the 3rd number produced is very predictable.

下面的程序演示了此问题。需要注意的是一个不同的种子值是通过在循环中使用的每个时间

The program below demonstrates the problem. Note that a different seed value is used each time through the loop.

using System;

class Program
{
    static void Main(string[] args)
    {
            // repeat experiment with different master RNGs
        for (int iMaster = 0; iMaster < 30; ++iMaster)
        {
                // create master RNG
            var rngMaster = new Random(iMaster + OFFSET);

                // obtain seed from master RNG
            var seed = rngMaster.Next();

                // create main RNG from seed
            var rngMain = new Random(seed);

                // print 3rd number generated by main RNG
            var ignore0 = rngMain.Next(LIMIT);
            var ignore1 = rngMain.Next(LIMIT);
            var randomNumber = rngMain.Next(LIMIT);
            Console.WriteLine(randomNumber);
        }
    }

    const int OFFSET = 0;
    const int LIMIT = 200;
}

我想这应该产生随机的输出,但在我的箱子实际的输出是:

I think this should produce random output, but the actual output on my box is:

84
84
84
84
84
84
84
84
84
84
84
...

任何人能解释这是怎么回事呢?改变OFFSET和LIMIT常数改变输出值,但它总是重复。

Can anyone explain what's going on here? Changing the OFFSET and LIMIT constants changes the output value, but it's always repeating.

推荐答案

欢迎非加密的强随机数发生器的世界。显然,建于.NET RNG具有使其输出84第3个号码,如果你把它限制在0到200的输出的倾向。看看该程序的以下版本中,更显示了什么是在输出回事。

Welcome to the world of non cryptographically strong RNGs. Apparently the built in .NET RNG has a tendency to make the 3rd number it outputs 84 if you limit it to 0 to 200 for its outputs. Take a look at the following version of the program, it shows more of what is going on in the output.

class Program
{
    static void Main(string[] args)
    {
        Console.WindowWidth = 44;
        Console.WindowHeight = 33;
        Console.BufferWidth = Console.WindowWidth;
        Console.BufferHeight = Console.WindowHeight;

        string template = "|{0,-5}|{1,-11}|{2,-5}|{3,-5}|{4,-5}|{5,-5}|";
        Console.WriteLine(template, "s1", "s2", "out1", "out2", "out3", "out4");
        Console.WriteLine(template, new String('-', 5), new String('-', 11), new String('-', 5), new String('-', 5), new String('-', 5), new String('-', 5));

        // repeat experiment with different master RNGs
        for (int iMaster = 0; iMaster < 30; ++iMaster)
        {
            int s1 = iMaster + OFFSET;
            // create master RNG
            var rngMaster = new Random(s1);

            // obtain seed from master RNG
            var s2 = rngMaster.Next();

            // create main RNG from seed
            var rngMain = new Random(s2);

            var out1 = rngMain.Next(LIMIT);
            var out2 = rngMain.Next(LIMIT);
            var out3 = rngMain.Next(LIMIT);
            var out4 = rngMain.Next(LIMIT);
            Console.WriteLine(template, s1, s2, out1, out2, out3, out4);
        }

        Console.ReadLine();
    }

    const int OFFSET = 0;
    const int LIMIT = 200;
}

下面是输出


|s1   |s2         |out1 |out2 |out3 |out4 |
|-----|-----------|-----|-----|-----|-----|
|0    |1559595546 |170  |184  |84   |84   |
|1    |534011718  |56   |177  |84   |123  |
|2    |1655911537 |142  |171  |84   |161  |
|3    |630327709  |28   |164  |84   |199  |
|4    |1752227528 |114  |157  |84   |37   |
|5    |726643700  |0    |150  |84   |75   |
|6    |1848543519 |86   |143  |84   |113  |
|7    |822959691  |172  |136  |84   |151  |
|8    |1944859510 |58   |129  |84   |189  |
|9    |919275682  |144  |122  |84   |28   |
|10   |2041175501 |30   |115  |84   |66   |
|11   |1015591673 |116  |108  |84   |104  |
|12   |2137491492 |2    |102  |84   |142  |
|13   |1111907664 |88   |95   |84   |180  |
|14   |86323836   |174  |88   |84   |18   |
|15   |1208223655 |60   |81   |84   |56   |
|16   |182639827  |146  |74   |84   |94   |
|17   |1304539646 |31   |67   |84   |133  |
|18   |278955818  |117  |60   |84   |171  |
|19   |1400855637 |3    |53   |84   |9    |
|20   |375271809  |89   |46   |84   |47   |
|21   |1497171628 |175  |40   |84   |85   |
|22   |471587800  |61   |33   |84   |123  |
|23   |1593487619 |147  |26   |84   |161  |
|24   |567903791  |33   |19   |84   |199  |
|25   |1689803610 |119  |12   |84   |38   |
|26   |664219782  |5    |5    |84   |76   |
|27   |1786119601 |91   |198  |84   |114  |
|28   |760535773  |177  |191  |84   |152  |
|29   |1882435592 |63   |184  |84   |190  |

因此​​,有主RND的第一输出和被链连接到第一的第二RNG的前几个输出之间的一些很强的相关性。在随机 RNG是不是设计为安全,它的设计是快,所以像你在这里看到的是什么是快速和安全之间的权衡。如果你不希望这样的事情发生,你需要使用一个cryptographicly安全的随机数发生器。

So there are some strong correlations between the first output of the master RND and the first few outputs of a second RNG that was chained off of the first. The Random RNG is not designed to be "secure" it is designed to be "fast", so things like what you are seeing here are the tradeoffs between being fast and secure. If you don't want things like this to happen you need to use a cryptographicly secure random number generator.

不过只是切换到密码学随机数发生器(CRNG)是不够的,你还需要你如何使用CRNG要小心。一个非常类似的问题发生与WEP的无线安全。根据在报头是可能的predict种子值(WEP密钥)的随机数发生器被用来保护连接什么给予什么四。虽然他们使用的CRNG(他们使用RC4),他们没有正确地使用它(你必须吐出几个1000次迭代的输出变为非predictable之前)。

However just switching to a Cryptographic Random Number Generator (CRNG) is not enough you still need to be careful how you use the CRNG. A very similar problem happened with WEP wireless security. Depending on what IV was given in the header it was possible to predict what the seed value (the WEP key) for the random number generator was used to protect the connection. Although they used a CRNG (they used RC4) they did not use it correctly (you have to spit out a few 1000 iterations before the output becomes non predictable).

这篇关于.NET框架:随机数发生器产生重复模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆