由于它是伪随机的,因此必须有某种方法来预测数字。
确实; 如果您知道内部状态(尤其是inext
,inextp
和SeedArray
- 总共 58int
个值),并且您知道将按确切顺序请求的确切操作(例如,请求Next()
, Next()
, 与请求 ,非常NextBytes()
不同, ) - 那么你可以做出完全准确的前向猜测。这就是种子 PRNG 的全部意义——它允许可重复的随机性,这在您需要能够重播事件的许多场景中很有用。Next()
NextBytes()
Next()
所以:我认为您永远无法取回原始种子,但要预测未来(而不是过去),您不需要种子 - 您只需要 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());
}
}