调用mt_rand($min, $max)
基本上等同于以下内容:
$rand_in_range_min_to_max = (int)($min + ($max - $min) * ($rand/mt_getrandmax()));
因此,不是从 0 到 2 31 -1 的理论范围中选择随机数,而是从$min
to中选择数字$max
。如果$min
大于0
或$max
小于1<<31-1
,仅此一项就已经减少了可能的种子值的数量。
现在,由于所提出的攻击是一种蛮力攻击,因此减少猜测次数也确实减少了完成蛮力过程的时间。
但是,由于暴力破解过程的结果值不是实际的随机值,而只是随机值映射到的值,因此攻击者需要检查映射到该暴力破解值的每个可能的输入值。该范围可以计算如下:
$rand_min = (int)(($rand_in_range_min_to_max - $min) / ($max - $min) * mt_getrandmax());
$rand_max = (int)($rand_min + mt_getrandmax() / ($max - $min + 1));
// range whose values are mapped onto $rand_in_range_min_to_max
$range = range($rand_min, $rand_max);
foreach ($range as $rand) {
assert($rand_in_range_min_to_max === (int)($min + ($max - $min) * ($rand/mt_getrandmax())));
}
由于范围内的每个数字都被相同地映射,它们都只是用于按顺序生成下一个随机数的潜在数字。为了明确无误地识别实际数字,攻击者最多需要mt_getrandmax() / ($max - $min)
随后生成的随机数。
因此,实际上,使用mt_rand($min, $max)
确实增加了攻击者找到实际种子的努力,因为他必须对多个随机值的种子进行暴力破解,并且他需要mt_getrandmax() / ($max - $min)
随后生成随机数来唯一识别正确的种子。