2 回答

TA貢獻1829條經驗 獲得超7個贊
簡短的回答,gmp_random_range():
$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 字節整數,如果有符號則表示-2?63到 2?63?-1 ,如果無符號則表示 0 到 2?64?-1。
PHP_INT_MAX在 32 位版本中是 4 字節值,但在 64 位版本中是 8 字節值。無論哪種情況,都會簽署。
因此,如果您可以安全地假設 64 位 PHP 并且您想要有符號的數字,那么您基本上就可以完成任何隨機生成函數。如果您需要加密安全數字,則可以使用random_int() ,否則可以使用mt_rand():
var_dump(random_int(0,?PHP_INT_MAX));var_dump(mt_rand(0,?PHP_INT_MAX));
但你想要無符號值,因此你必須切換到字符串。一旦到達那里,一個明顯的方法是生成兩個整數并將它們連接為字符串 - 棘手的部分是確保不會溢出范圍。作為替代方案,您可以使用 GMP 任意精度擴展,它有一個專用功能。
PS你實際上提到了BIGINT(8)
。8 只是從兼容客戶端打印時的顯示尺寸,它不代表存儲范圍,也不會以任何方式強制執行。由于您明確表示期望最多 20 位數字,因此它只是一種誤導。

TA貢獻1831條經驗 獲得超4個贊
您可以使用此函數生成超過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'));
- 2 回答
- 0 關注
- 145 瀏覽
添加回答
舉報