mt_rand() 总是给我相同的数字

mt_rand() gives me always the same number

我的这个功能总是有问题 mt_rand() 给我相同的号码:

$hex = 'f12a218a7dd76fb5924f5deb1ef75a889eba4724e55e6568cf30be634706bd4c'; // i edit this string for each request
$hex = hexdec($hex);    
mt_srand($hex);
$hex = sprintf("%04d", mt_rand('0','9999'));

$hex总是变,但结果总是一样4488.

编辑

$hex = str_split($hex);
$hex = implode("", array_slice($hex, 0, 7));
mt_srand($hex);
$number = sprintf("%04d", mt_rand('0','9999'));

http://php.net/manual/en/function.mt-srand.php

您的问题是,您总是在变量 $hex 中得到一个浮点值。函数 mt_srand() 也可以在 manual:

中看到

void mt_srand ([ int $seed ] )

需要一个整数。所以它所做的是,它只是尝试将您的浮点值转换为整数。但由于失败,它将始终 return 0。

所以最后你总是以种子 0 结束,然后也以相同的 "random" 数字结束。

如果你这样做,你可以看到这个:

var_dump($hex);

输出:

float(1.0908183557664E+77)

如果你想知道转换后最终会是哪个整数,你可以使用这个:

var_dump((int)$hex);

你会发现它永远是 0。


此外,如果您感兴趣,为什么您的数字最终会变成浮点数,这仅仅是因为整数溢出,因为您的数字太大并且符合 manual:

If PHP encounters a number beyond the bounds of the integer type, it will be interpreted as a float instead. Also, an operation which results in a number beyond the bounds of the integer type will return a float instead.

如果你这样做:

echo PHP_INT_MAX;

您将获得 int 的最大值,即:

28192147483647      //32 bit
9223372036854775807 //64 bit

编辑:

那么现在如何解决这个问题并仍然确保获得随机数?

嗯,第一个想法可能只是检查该值是否大于 PHP_INT_MAX,如果是,则将其设置为其他数字。但我假设你似乎总是有这么大的十六进制数。

所以我会推荐你​​这样的东西:

$arr = str_split($hex);
shuffle($arr);
$hex = implode("", array_slice($arr, 0, 7));

这里我只是把你的号码拆分成一个数组str_split(), to then shuffle() the array and after this I implode() the first 7 array elements which I get with array_slice()

完成此操作后,您可以将它与 hexdec() 一起使用,然后在 mt_srand().

中使用它

还有为什么我只得到前7个元素?仅仅是因为这样我就可以确保我没有达到 PHP_INT_MAX 值。