我要做的是预测由System.Random
从现有56个随机整数序列生成的一系列整数中的下一个数字。
我知道System.Random
使用D. E. Knuth的书中的减法算法,给定最后55个整数,序列中的下一个整数将是:
seq[n] = (seq[n-55] - seq[n-24]) % m
所以我尝试填充一个随机列表并用蛮力找到m
。
var rnd = new Random();
var list = new List<int>();
for(var i=0; i< 56; i++)
list.Add(rnd.Next());
var n1 = list[0];
var n2 = list[31];
var n = list[55];
Console.WriteLine("{0} = ({1} - {2}) % m", n, n1, n2);
for(var i = 1; i< int.MaxValue; i++)
{
if (n == (n1 - n2) % i)
Console.WriteLine("m = {0}", i);
}
它不起作用。然后我注意到在System.Random
实现中有一个显而易见的bug,他们使用了34而不是24。我也试过了,再次没有运气。
如果有人能在这里告诉我我做错了什么,我真的很感激。
答案 0 :(得分:4)
如果您尝试复制System.Random
目前的内容,我建议您查看source code itself。
从快速浏览一下代码,看起来与m值最接近的是MBIG(int.MaxValue
)。每个得到的随机值都限制在0和MBIG之间:
int retVal; int locINext = inext; int locINextp = inextp;
if (++locINext >=56) locINext=1;
if (++locINextp>= 56) locINextp = 1;
retVal = SeedArray[locINext]-SeedArray[locINextp];
if (retVal == MBIG) retVal--;
if (retVal<0) retVal+=MBIG;
SeedArray[locINext]=retVal;
inext = locINext;
inextp = locINextp;
return retVal;