Сгенерировать случайное число с предопределенной длиной PHP
Я пытаюсь создать функцию с помощью mt_rand (), чтобы создать действительно случайное число, так как rand () просто недостаточно.
проблема в том, что мне нужно предварительно определить длину числа, скажем, мне нужно 10-значное случайное число.
в любом случае, я возился, и вот что я придумал:
function randomNumber($length) {
$min = str_repeat(0, $length-1) . 1;
$max = str_repeat(9, $length);
return mt_rand($min, $max);
}
теоретически это должно работать (насколько я могу судить), но это не так. Длина полностью случайна, и она также выбрасывает отрицательный ценности.
какие идеи?
8 ответов
если у вас нет одной из этих квантово-статических штуковин, вы не можете получить действительно случайное число. Однако в ОС на базе Unix /dev/urandom
работает для "большей случайности", если вам это действительно нужно.
в любом случае, если вы хотите n-значное число, это именно то, что вы должны получить: n отдельных цифр.
function randomNumber($length) {
$result = '';
for($i = 0; $i < $length; $i++) {
$result .= mt_rand(0, 9);
}
return $result;
}
причина, по которой ваш существующий код не работает, заключается в том, что 0000...01
по-прежнему 1
to mt_rand
, а также mt_rand
диапазон не бесконечен. Отрицательное число целочисленные переполнения.
вот что я использую:
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 в любом другом месте.
коротко и ясно:
Я предполагаю только законные числа, а не строки, такие как 00010. Попробуйте использовать размер вашего номера, чтобы быть:
$min = pow(10, $length - 1) ;
$max = pow(10, $length) - 1;
return mt_rand($min, $max);
единственный, который не работает, когда длина равна 1, однозначное число " 0 " не будет возможным значением для возврата.
function randomNDigitNumber($digits)
{
$returnString = mt_rand(1, 9);
while (strlen($returnString) < $digits) {
$returnString .= mt_rand(0, 9);
}
return $returnString;
}
первая строка гарантирует, что никакое "0" не предшествует любому числу, например значениям, таким как 012, 0598... будет отброшен, остальное легко
используйте это для строк определенной длины с буквами и цифрами. Проверенный.
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;
}
вы не должны начинать с длины, ограничивающей случайные числа. Скорее накопите достаточно длинный выход, а затем отрежьте его до нужной длины:
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);
заполнение должно быть там, потому что даже нули генерируются случайным образом и должны быть сохранены.
function randomNumber($length) {
$min = 1 . str_repeat(0, $length-1);
$max = str_repeat(9, $length);
return mt_rand($min, $max);
}
у вас есть конкат 1 в неправильном месте, ваш диапазон-это для $length=2: {01,99} - иногда его 01-09, который представлен как 1-9 не 01-09. Просто начните с 10: {10,99} будет ваш выбор.
Как насчет этого:
function random($len)
{
static $track = [];
$min = 1 . str_repeat(0, $len - 1);
$max = str_repeat(9, $len);
$num = mt_rand($min, $max);
// was this number generated before?
if (in_array($num, $track))
{
// try again
return random($len);
}
return $track[] = $num;
}
отслеживание сгенерированных чисел через статическую переменную (которая инициируется один раз) предотвратит генерирование одного и того же числа дважды, если вы не пройдете через весь диапазон, и в этом случае вы застряли в бесконечном цикле. Например:
for ($i = 0; $i < 10; $i++)
{
random(1);
}