确定C#随机实例的种子

Cor*_*rne 3 c# random prediction

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

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

new Random() == new Random(Environment.TickCount)
Run Code Online (Sandbox Code Playgroud)

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

是否有可能确定Random类实例的种子?如果你可以在实例化Random类时知道Environment.TickCount,可以预测随机数,但我不知道是否可以完成.

Mar*_*ell 6

由于它是伪随机的,必须有一些方法来预测数字.

确实; 如果你知道的内部状态(尤其是inext,inextpSeedArray-所以58个int共值),并且你知道要去的确切顺序被要求(例如,要求精确的操作Next(),Next(),NextBytes()是要求非常不同Next(),NextBytes(),Next()) - 那么你可以做出完全准确的前瞻性猜测.这就是种子PRNG 的全部要点 - 它允许可重复的随机性,这在您需要能够重放事件的许多场景中都很有用.

所以:我认为你不能找回原始的种子,但是为了预测未来(而不是过去)你不需要种子 - 你只需要58个int值.

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

例如:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)