生成一个预先定义长度的随机数 PHP

问题描述 投票:0回答:12

我正在尝试使用 mt_rand() 创建一个函数来生成真正的随机数,因为 rand() 还不够。

问题是我需要预先定义数字的长度,比如说我需要一个10位随机数。

无论如何,我一直在搞乱,这就是我想出的:

    function randomNumber($length) {
        $min = str_repeat(0, $length-1) . 1;
        $max = str_repeat(9, $length);
        return mt_rand($min, $max);   
    }

理论上这应该有效(据我所知),但事实并非如此。长度是完全随机的,它也会抛出负值。

有什么想法吗?

php random numbers
12个回答
40
投票

如果“真正的随机数”是指加密安全的随机数,请确保使用

random_int
而不是
mt_rand
mt_rand
不基于 CSPRNG。 如果您不知道是否需要 CSPRNG,请无论如何使用
random_int
– 它并不慢。

如果您想要一个 n 位数字字符串,这正是您应该得到的:n 个单独的数字。

function randomNumber($length) { $result = ''; for ($i = 0; $i < $length; $i++) { $result .= random_int(0, 9); } return $result; }
您现有的代码不起作用的原因是因为

0000...01

仍然是
1
mt_rand
,而且
mt_rand
的范围不是无限的。负数是整数溢出。


10
投票
只需指定 rand 方法的范围,如果您需要 4 位随机数,则只需将其用作

rand(1000,9999);
    

8
投票
简短而甜蜜:

我假设只有合法的数字,而不是像 00010 这样的字符串。尝试使用你的数字的大小:

$min = pow(10, $length - 1) ; $max = pow(10, $length) - 1; return mt_rand($min, $max);

唯一不起作用的是当长度为 1 时,单个数字“0”将不会成为可能返回的值。


7
投票
这是我正在使用的:

function random_number($length) { return join('', array_map(function($value) { return $value == 1 ? mt_rand(1, 9) : mt_rand(0, 9); }, range(1, $length))); }

一行,又好又简单!该数字永远不会以 0 开头,并且在任何其他位置都允许 0。


2
投票
function randomNDigitNumber($digits) { $returnString = mt_rand(1, 9); while (strlen($returnString) < $digits) { $returnString .= mt_rand(0, 9); } return $returnString; }

第一行确保任何数字前面都没有“0”,例如像 012、0598... 这样的值将被丢弃,其余的很简单


1
投票
function randomNumber($length) { $min = 1 . str_repeat(0, $length-1); $max = str_repeat(9, $length); return mt_rand($min, $max); }

您的 concat 1 位于错误的位置,您的范围是 $length=2: {01,99} - 有时是 01-09,表示为 1-9 而不是 01-09。从 10 开始:{10,99} 将是您的范围。


1
投票
将此用于包含字母和数字的一定长度的字符串。已测试。

protected function randomToken($length = 4, $result='') { for($i = 0; $i < $length; $i++) { $case = mt_rand(0, 1); switch($case){ case 0: $data = mt_rand(0, 9); break; case 1: $alpha = range('a','z'); $item = mt_rand(0, 25); $data = strtoupper($alpha[$item]); break; } $result .= $data; } return $result; }
    

0
投票
您不应该从限制随机数的长度开始。而是积累足够长的输出,然后将其切割到合适的长度:

while (strlen($value) < $length) { $value .= str_pad(mt_rand(00000, 99999), 5, "0", STR_PAD_LEFT); } // as pairs of five were added before, eventually remove some again return substr($value, 0, $length);

填充应该在那里,因为即使是零也是随机生成的,应该保留。


0
投票
假设您使用的范围较小并且不想生成相同的数字两次,这样怎么样:

function random(int $len): int { static $track = []; $min = 1 . str_repeat(0, $len - 1); $max = str_repeat(9, $len); $num = mt_rand($min, $max); // if was generated before, try again if (in_array($num, $track)) { return random($len); } // store and return return $track[] = $num; }
通过静态变量(仅启动一次)跟踪生成的随机数,将防止生成相同的数字两次,但请注意,如果超过 

$len

 规定的唯一可能性的数量,您将陷入无限循环。例如,您不能调用 
random(1)
 超过 9 次,因为 
$len
 为 1,并且只有 9 种独特的可能性(不包括 0),因此您需要了解需要多少随机数或选择较大的随机数足够了
$len
,不用担心。


0
投票
如果环境是本地的,则无需生成随机数,mt_rand 与 rand 类似,但速度快四倍

protected function generateRandomNumber(int $length = 6) { $rand = ''; $env = env('APP_ENV'); for ($i = 1; $i <= $length; $i++) { $rand .= ($env == 'local') ? $i : mt_rand(($i == 1) ? 1 : 0, 9); } return (int) $rand; }
    

0
投票
function randomNumber($length) { $bytes = random_bytes($length / 2); /* Generate random bytes (half the length because each byte is represented by two hexadecimal characters) */ $uniqueId = bin2hex($bytes); // Convert bytes to hexadecimal string return $uniqueId }
    

-1
投票
这里我需要一个长度为10的随机数, 这是我正在使用的:

$characters = rand(1111111111, 9999999999);


    

© www.soinside.com 2019 - 2024. All rights reserved.