确定 C# 随机实例的种子 [英] Determine the seed of C# Random Instance

查看:35
本文介绍了确定 C# 随机实例的种子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出于兴趣,我正在玩 C# 附带的 Random 类.我试图预测未来.由于它是伪随机的,因此必须有某种方法来预测数字.到目前为止我能想到的唯一方法是蛮力(获取所有可能的种子并找到其中随机数的模式),但我相信它的处理能力太强了,因为种子可以是从 -2,147,483,647 到 2,147,483,647 的任何东西.

Out of interest, I am playing around with the Random class that comes with C#. I am trying to predict the future. As it is pseudo random, there must be some way to predict the numbers. The only way I can think of so far is brute force (Getting all possible seeds and finding the pattern of the random numbers in them) but I believe it will be too much processing power as the seed can be anything from -2,147,483,647 to 2,147,483,647.

到目前为止,我已经确定:

So far I have determined that:

new Random() == new Random(Environment.TickCount)

并且这两个类将以相同的顺序提供相同的随机数.

and that both these classes will provide the same random numbers in the same order.

是否可以通过任何方式确定 Random 类实例的种子?如果你能在实例化Random类时知道Environment.TickCount,就可以预测随机数,但我不知道能不能做到.

Is it in any way possible to determine the seed of the Random class instance? If you could know the Environment.TickCount when the Random class was instantiated, the random numbers could be predicted, but I have no idea whether it could be done.

推荐答案

因为它是伪随机的,所以必须有某种方法来预测数字.

As it is pseudo random, there must be some way to predict the numbers.

确实;如果你知道内部状态(特别是 inext,inextpSeedArray - 所以总共有 58 个 int 值), 您知道将按确切顺序请求的确切操作(例如,请求 Next(), Next()>、NextBytes() 与请求 Next()NextBytes()Next() 非常不同) - 那么你可以做出完全准确的前向猜测.这是种子 PRNG 的全部 - 它允许可重复的随机性,这在您需要能够重播事件的许多场景中非常有用.

Indeed; if you know the internal state (in particular inext,inextp and SeedArray - so 58 int values in total), and you know the exact operations that are going to be requested in the exact order (for example, asking for Next(), Next(), NextBytes() is very different to asking for Next(), NextBytes(), Next()) - then you could make entirely accurate forward guesses. That is the entire point of a seeded PRNG - it allows for repeatable randomness, which is useful in many scenarios when you need to be able to replay events.

所以:我认为您永远无法取回原始的种子,但是要预测未来(而不是过去),您不需要种子 - 您只需要 58 个 int 值.

So: I don't think you could ever get back the original seed, but to predict the future (rather than the past) you don't need the seed - you just need 58 int values.

但是!随机性重要的任何事情都应该使用加密随机提供者 - 而这些不可可重复或可猜测.

However! Anything where the randomness matters should be using the cryptographic random providers - and those are not repeatable or guessable.

例如:

static class Program {
    static Random Clone(this Random source)
    {
        var clone = new Random();
        var type = typeof(Random);
        var field = type.GetField("inext",
            BindingFlags.Instance | BindingFlags.NonPublic);
        field.SetValue(clone, field.GetValue(source));
        field = type.GetField("inextp",
            BindingFlags.Instance | BindingFlags.NonPublic);
        field.SetValue(clone, field.GetValue(source));
        field = type.GetField("SeedArray",
            BindingFlags.Instance | BindingFlags.NonPublic);
        int[] arr = (int[])field.GetValue(source);
        field.SetValue(clone, arr.Clone());
        return clone;
    }
    static void Main()
    {
        Random rand = new Random();
        var clone = rand.Clone();
        Console.WriteLine("My predictions:");
        Console.WriteLine(clone.Next());
        Console.WriteLine(clone.Next());
        Console.WriteLine(clone.Next());
        Console.WriteLine("Actual:");
        Console.WriteLine(rand.Next());
        Console.WriteLine(rand.Next());
        Console.WriteLine(rand.Next());
    }
}

这篇关于确定 C# 随机实例的种子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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