使用 PHP 的随机变长 bigint(8) 数?
Random variable length bigint(8) number using PHP?
使用 php7,我想生成一个随机可变长度 unsigned bigint(8) 数字 - 在 1 和 18446744073709551615 之间
我发现 但 mcrypt_create_iv 已在 php 7.
中弃用
谢谢
$from = 0;
$to = '18446744073709551615';
$random = gmp_random_range($from, $to);
var_dump($random, (string)$random);
例如:
object(GMP)#1 (1) {
["num"]=>
string(20) "10366718409313808674"
}
string(20) "10366718409313808674"
补充题外话:
MySQL的BIGINT是一个8字节的整数,意思是-263到263-1 如果有符号,0 到 264-1 如果没有符号.
PHP_INT_MAX 在 32 位版本中是一个 4 字节的值,但在 64 位版本中是一个 8 字节的值。两种情况都已签名。
因此,如果您可以安全地假设 64 位 PHP 并且您想要带符号的数字,那么您基本上可以完成任何随机生成函数。您可以使用 random_int() if you're after cryptographically secure numbers or mt_rand() 否则:
var_dump(random_int(0, PHP_INT_MAX));
var_dump(mt_rand(0, PHP_INT_MAX));
但是您需要无符号值,因此您必须切换到字符串。在那里,一个明显的方法是生成两个整数并将它们连接成字符串——棘手的部分是确保你不会溢出你的范围。作为替代方案,您可以使用 GMP 任意精度扩展,它有专门的功能。
P.S。你居然提到了BIGINT(8)
。这 8 只是从兼容客户端打印时的显示大小,它不代表存储范围,也不是以任何方式强制执行的。并且由于您明确表示您期望最多 20 位数字,所以这只是误导。
此函数可用于生成从 1
到任何超过 PHP_INT_MAX
的最大值的数字字符串(最大值和结果都必须是字符串)
重要:
不要将其用于密码学,因为并非所有数字都没有平等的机会被选中:
- 结果“1”的机会加倍,因为我们将零默认为“1”
- 我们随机选择每个字符,因此根据选择的最大值,并非所有数字都有相同的机会
<?php
function notCryptoRandomDecimalString($maxStrValue){
$result = '';
$maxBegin = '';
for($i = 0; $i < strlen($maxStrValue); $i++){
$maxDigit = $maxStrValue[$i];
//if beginning of the result is same than beginning of the max,
//we limit random to current char from maximum, or else it can be from 0 to 9
if($result === $maxBegin){
$result .= random_int(0, $maxDigit);
}else{
$result .= random_int(0, 9);
}
$maxBegin .= $maxDigit;
}
//remove leading zeroes
$result = ltrim($result, '0');
//if zero was picked, default to 1
if($result === ''){
$result = '1';
}
return $result;
}
echo(notCryptoRandomDecimalString('18446744073709551615'));
使用 php7,我想生成一个随机可变长度 unsigned bigint(8) 数字 - 在 1 和 18446744073709551615 之间 我发现 但 mcrypt_create_iv 已在 php 7.
中弃用谢谢
$from = 0;
$to = '18446744073709551615';
$random = gmp_random_range($from, $to);
var_dump($random, (string)$random);
例如:
object(GMP)#1 (1) {
["num"]=>
string(20) "10366718409313808674"
}
string(20) "10366718409313808674"
补充题外话:
MySQL的BIGINT是一个8字节的整数,意思是-263到263-1 如果有符号,0 到 264-1 如果没有符号.
PHP_INT_MAX 在 32 位版本中是一个 4 字节的值,但在 64 位版本中是一个 8 字节的值。两种情况都已签名。
因此,如果您可以安全地假设 64 位 PHP 并且您想要带符号的数字,那么您基本上可以完成任何随机生成函数。您可以使用 random_int() if you're after cryptographically secure numbers or mt_rand() 否则:
var_dump(random_int(0, PHP_INT_MAX));
var_dump(mt_rand(0, PHP_INT_MAX));
但是您需要无符号值,因此您必须切换到字符串。在那里,一个明显的方法是生成两个整数并将它们连接成字符串——棘手的部分是确保你不会溢出你的范围。作为替代方案,您可以使用 GMP 任意精度扩展,它有专门的功能。
P.S。你居然提到了BIGINT(8)
。这 8 只是从兼容客户端打印时的显示大小,它不代表存储范围,也不是以任何方式强制执行的。并且由于您明确表示您期望最多 20 位数字,所以这只是误导。
此函数可用于生成从 1
到任何超过 PHP_INT_MAX
的最大值的数字字符串(最大值和结果都必须是字符串)
重要: 不要将其用于密码学,因为并非所有数字都没有平等的机会被选中:
- 结果“1”的机会加倍,因为我们将零默认为“1”
- 我们随机选择每个字符,因此根据选择的最大值,并非所有数字都有相同的机会
<?php
function notCryptoRandomDecimalString($maxStrValue){
$result = '';
$maxBegin = '';
for($i = 0; $i < strlen($maxStrValue); $i++){
$maxDigit = $maxStrValue[$i];
//if beginning of the result is same than beginning of the max,
//we limit random to current char from maximum, or else it can be from 0 to 9
if($result === $maxBegin){
$result .= random_int(0, $maxDigit);
}else{
$result .= random_int(0, 9);
}
$maxBegin .= $maxDigit;
}
//remove leading zeroes
$result = ltrim($result, '0');
//if zero was picked, default to 1
if($result === ''){
$result = '1';
}
return $result;
}
echo(notCryptoRandomDecimalString('18446744073709551615'));