PHP Rand(),是否可以猜测序列中的下一个数字?并产生更好的数字

时间:2012-01-12 16:18:56

标签: php random

如果我使用$num=rand(0, 1000);生成一个数字,是否可以猜出下一个数字是什么?

我是否需要记录一定数量的先前生成的数字?我将如何计算下一个数字呢?

其他信息:

来自random.org -

PHP Rand() image PHP Rand()图片

True random image真随机图片

感谢Derobert的回答:

我使用他的答案中公布的方法生成以下图像

openssl image OpenSSL图片

我使用以下代码执行此操作:

// Requires the GD Library
header("Content-type: image/png");
$im = imagecreatetruecolor(512, 512)
    or die("Cannot Initialize new GD image stream");
$white = imagecolorallocate($im, 255, 255, 255);
for ($y=0; $y<512; $y++) {
    for ($x=0; $x<512; $x++) {
        if (random() === 1) {
            imagesetpixel($im, $x, $y, $white);
        }
    }
}       
imagepng($im);
imagedestroy($im);

function random(){
    $num = unpack('L', openssl_random_pseudo_bytes(4, $is_strong));


    if (!$is_strong) {
        echo 'error';
    }
    else{
        $lastDigit=substr($num[1], strlen($num[1])-1, 1);
        if($lastDigit<=4) return 0;
        return 1;
    }
}

Bo

的信用

3 个答案:

答案 0 :(得分:4)

是的,有可能,php的rand显然只是使用底层C库的rand,这是一个伪随机数生成器。

您需要观察多少输出取决于C库使用的确切算法,这些算法因平台而异(有时甚至是版本到版本)。您需要观察的输出数量可能少于十个。

如果您的C库特别糟糕,可以尝试使用Mersenne Twister算法的mt_rand。请注意,这仍然是可预测的。

如果您需要不可预测的随机数,请使用openssl_random_pseudo_bytes并确保之后的crypto_strong为真。请注意,它返回二进制字符串;要得到一个数字,你必须使用unpack

之类的东西
$num = unpack('L', openssl_random_bytes(4, $is_strong));
if (!$is_strong) {
    ... // handle error
}

另请注意,将返回介于0和2³²= 4294967296之间的数字,而不是0-1000,因此您需要处理该数字。

答案 1 :(得分:1)

rand()生成伪随机序列。如果您想要一个可预测的(可读取的可重复)序列,则需要使用srand()为随机生成器播种。

尝试连续两次运行以下脚本:

<?php
$seed = 2;
srand($seed);
foreach(range(1, 100) as $i) var_dump(rand(0, 100));

答案 2 :(得分:0)

PHP将为同一种子生成相同的数字序列。所以你必须找出种子,然后记录数字:

php > srand(1);
php > echo rand(1,100);
85
php > echo rand(1,100);
40
php > srand(1);
php > echo rand(1,100);
85
php > echo rand(1,100);
40

或者你看一下PHP源代码!