PHP rand () excludes certain numbers

I have it:

<?php $n = rand(1,1600); echo $n ?> 

I want to exclude from random numbers, say, 234, 1578, 763, 1274 and other numbers. How can I do it?

+11
source share
10 answers
 <?php while( in_array( ($n = rand(1,1600)), array(234, 1578 ,763 , 1274) ) ); 
+12
source

try it

 do { $n = rand(1,1600); } while(in_array($n, array(234, 1578 ,763 , 1274 )); echo $n; 
+10
source

Check not the number you don't need if it gets a new random number.

 function getRandomNumber() { do { $n = mt_rand(1,1600); } while(in_array($n, array(234,1578, 763, 1274))); return $n; } 
+8
source

Or avoid creating loops with random (possibly infinite) runtimes:

 /** * Returns a random integer between $min and $max (inclusive) and * excludes integers in $exarr, returns false if no such number * exists. * * $exarr is assumed to be sorted in increasing order and each * element should be unique. */ function random_exclude($min, $max, $exarr = array()) { if ($max - count($exarr) < $min) { return false; } // $pos is the position that the random number will take // of all allowed positions $pos = rand(0, $max - $min - count($exarr)); // $num being the random number $num = $min; // while $pos > 0, step to the next position // and decrease if the next position is available for ($i = 0; $i < count($exarr); $i += 1) { // if $num is on an excluded position, skip it if ($num == $exarr[$i]) { $num += 1; continue; } $dif = $exarr[$i] - $num; // if the position is after the next excluded number, // go to the next excluded number if ($pos >= $dif) { $num += $dif; // -1 because we're now at an excluded position $pos -= $dif - 1; } else { // otherwise, return the free position return $num + $pos; } } // return the number plus the open positions we still had to go return $num + $pos; } 

This function selects a random position and passes an array of exceptions to find a free position. Opening hours depend on the number of rooms to be excluded. If you want to exclude certain ranges, you can adapt the algorithm to take this into account.

+1
source

Always use cryptographically robust algorithms to generate random numbers:

 /** * @param int $from From number * @param int $to To number * @param array $excluded Additionally exclude numbers * @return int */ function randomNumber($from, $to, array $excluded = []) { $func = function_exists('random_int') ? 'random_int' : 'mt_rand'; do { $number = $func($from, $to); } while (in_array($number, $excluded, true)); return $number; } var_dump(randomNumber(1, 100)); var_dump(randomNumber(1, 10, [5, 6, 7, 8])); var_dump(randomNumber(1, 100, range(10, 90))); 

I would also recommend using the paragonie / random_compat library for compatibility when using multiple versions of PHP.

+1
source

You can create an array with real numbers.

Then your random number generation should return an index into this array.

0
source

If you have too many numbers to exclude, it’s easier and faster to just try again if you find an unwanted number:

 $n = 0; while (in_array($n, array(0, 234, 1578 ,763 , 1274))) { $n = rand(1,1600); } echo $n; 
0
source

Another solution for this may be as follows:

 function random_number($min, $max, $exclude) { $number = rand($min, $max); if(in_array($number, $exclude)) { random_number($min, $max, $exclude); } else { return $number; } } $number = random_number(1,10, [2,5,6]); 
0
source

As the volume of blacklisted integers approaches the size of the whole range of integers, it becomes more and more convincing to listen to @regenschein's advice.

A non-iterative approach might look like this:

 $range = range(1, 1600); $blacklist = [234, 1578, 763, 1274]; // 4 blacklisted versus 1600 full range is NOT compelling $valids = array_diff($range, $blacklist); echo array_values($valids)[rand(0, count($valids) - 1)]; // or echo $valids[array_rand($valids)]; // the two approaches use different randomizers 

Or, if you are just as happy, you can do:

 $blacklist = [234, 1578, 763, 1274]; $range = range(1, 1600); $valids = array_diff($range, $blacklist); shuffle($valids); echo $valids[0]; 

* Please note that array_diff() especially array_diff() if you want to pass multiple arrays of blacklist - just separate them with commas.

For instance:

 var_export($valids = array_diff(range(1, 100), range(5, 50), range(61, 99), [55])); 

Output:

 array ( 0 => 1, 1 => 2, 2 => 3, 3 => 4, 50 => 51, 51 => 52, 52 => 53, 53 => 54, 55 => 56, 56 => 57, 57 => 58, 58 => 59, 59 => 60, 99 => 100, ) 
0
source

I know this is a bit outdated, but I think the operation is trying to shuffle integers. If so, then the following method is better

 $array = array(1,2,3,4,5,6,7); shuffle($array); 

This code randomizes the order of the exact elements of the array without repeating and returns the result inside the array itself.

0
source

Source: https://habr.com/ru/post/947302/


All Articles