Я пытаюсь создать функцию, используя mt_rand (), чтобы генерировать действительно случайное число, так как rand () просто недостаточно.
Проблема в том, что мне нужно предварительно определить длину числа, скажем, мне нужно 10-значное случайное число.
Во всяком случае, я возился, и это то, что я придумал:
function randomNumber($length) { $min = str_repeat(0, $length-1) . 1; $max = str_repeat(9, $length); return mt_rand($min, $max); }
В теории, которая должна работать (насколько я могу судить), но это не так. Длина полностью случайна, и она также выдает отрицательные значения.
Есть идеи?
Если у вас нет одной из этих квантово-статических штучек, вы не сможете получить действительно случайное число. Однако в ОС на основе 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
до mt_rand
, а также то, что диапазон mt_rand
не бесконечен. Отрицательные числа являются целыми переполнениями.
Короткие и сладкие:
Я принимаю только законные числа, а не строки, такие как 00010. Попробуйте использовать размер вашего номера:
$min = pow(10, $length - 1) ; $max = pow(10, $length) - 1; return mt_rand($min, $max);
Единственное, что не работает, – это когда длина равна 1, одно число с цифрой «0» не может быть возвращено.
Вот что я использую:
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 в любом другом месте.
Вы не должны начинать с длины, ограничивающей случайные числа. Скорее накапливайте достаточно длинный вывод, а затем разрезайте его на нужную длину:
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); }
у вас есть ваш concat 1 в неправильном месте, ваш диапазон – это для $ length = 2: {01,99} – иногда его 01-09, который представлен как 1-9, а не 01-09. Просто начните с 10: {10,99} будет вашим диапазоном.
Спасибо за этот пример. Я добавил письма к простоте. Это отлично работает для меня, поскольку я использую это с дополнительными токенами для проверки.
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, 26); $data = strtoupper($alpha[$item]); break; } $result .= $data; } return $result; }
function randomNDigitNumber($digits) { $returnString = mt_rand(1, 9); while (strlen($returnString) < $digits) { $returnString .= mt_rand(0, 9); } return $returnString; }
Первая строка гарантирует, что «0» не будет предшествовать любому числу, например значения 012, 0598 … будут отброшены, остальное легко