【发布时间】:2010-12-23 23:55:48
【问题描述】:
在其他语言中,我会分部分生成它并将其存储在字符串中,但是使用 PHP,您无法选择数据类型,因此它不起作用,它会自动设置为整数,然后只能存储到最大值整数大小。
有什么解决办法吗?
【问题讨论】:
-
使用 GMP 扩展,
Alphabet::convert(\random_bytes(32), Alphabet::BYTE, Alphabet::DECIMAL)应该可以解决问题。
在其他语言中,我会分部分生成它并将其存储在字符串中,但是使用 PHP,您无法选择数据类型,因此它不起作用,它会自动设置为整数,然后只能存储到最大值整数大小。
有什么解决办法吗?
【问题讨论】:
Alphabet::convert(\random_bytes(32), Alphabet::BYTE, Alphabet::DECIMAL) 应该可以解决问题。
是的,您可以获取一些随机数据(例如来自/dev/urandom 或openssl_random_pseudo_bytes)。
然后将数据转换为其十进制表示,例如使用bcmath 或 gmp。请参阅this answer 了解如何执行此操作。
【讨论】:
我遇到了同样的问题。我有一个函数需要生成一个从 0 到 2^32-1 的随机数(将其表示为 8 位十六进制字符串)。 mt_rand() 只生成 0 到 2^31-1 之间的数字。
这失败了:
return hexdec(mt_rand(0,4294967295));
我用一行代码解决了这个问题:
return sprintf("%04X%04X", (mt_rand(0,65535)), (mt_rand(0,65535)));
这正是您所建议的,将随机化分解为多个部分。它生成两个随机数,每个从 0 到 2^16-1 (65,535)(十六进制 0000 到 FFFF),然后使用 sprintf 将它们连接在一起,以将结果补零为十六进制字符串。
从 0 到 2^32-1(十六进制 00000000 到 FFFFFFFF)的每个数字都是可能的。如果你想要一个 48 位随机十六进制数(十六进制 000000000000 到 FFFFFFFFFFFF),你可以这样扩展:
return sprintf("%04X%04X%04X", (mt_rand(0,65535)), (mt_rand(0,65535)), (mt_rand(0,65535)));
这对我有用!
【讨论】:
mt_rand(0, 10000) 将生成四位数的随机数。多次调用,连接结果:
mt_rand(0, 10000) . mt_rand(0, 10000) . mt_rand(0, 100) - 10 位长号码。
这有很多问题,但对于您的特定用例来说可能已经足够了。
【讨论】:
我会做这样的事情:
function getBigRandom($length, $space = '0123456789', $trim = true) {
$str = '';
$spaceLen = strlen($space);
for ($i = 0; $i < $length; $i++) {
$str .= $space[mt_rand(0, $spaceLen - 1)];
}
if ($trim) {
$str = ltrim($str, '0');
}
return $str;
}
用法:
$random = getBigRandom(15); // Generate up to a 15 digit random number
随机分布应该是相当均匀的,因为每个小数位都有相同的概率成为每种类型的值...使用默认参数调用它会生成一个数字。如果你想生成一个字符串(盐等),你可以这样做:
$random = getBigRandom(
128,
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
false
);
【讨论】:
$i = (int) $i;
你可以声明类型。
【讨论】:
int 类型可以处理的随机数有什么关系...