krishna koti
krishna koti

Reputation: 739

PHP Generate random number without repetition without loop for mt_rand and without using range() and shuffle()

I am looking for a way to generate a specific quantity of unique random numbers (say 10,000), within a specific range of numbers like (000000000,999999999).

I'd like to do this without repeatedly using rand() or mt_rand() under a for loop as this would be computationally inefficient.

Are there any PHP libraries, or solutions which meets these requirements?

Upvotes: 2

Views: 508

Answers (2)

rossum
rossum

Reputation: 15693

One method is to use a Format Preserving Encryption, with the output limited to the range 0 to 999999999. If you encrypt the numbers 0 to 9,999 you will get 10,000 unique outputs in the required range. With an encryption, unique inputs guarantee unique outputs as long as you don't change the key.

Upvotes: 1

num8er
num8er

Reputation: 19372

1) Create a class that keeps state of generation:

class Randomizer {
  private $min;
  private $max;
  private $maxGeneration; 

  public function __construct($min = 0, $max = 100) {
    if ($min >= $max) {
      throw new Exception('Minimal value is more than or equal to Max value');
    }

    if ($max - $min < 3) {
      throw new Exception('Nothing to randomize');
    } 

    $this->min = $min;
    $this->max = $max;
    $this->maxGeneration = $max - $min - 1;
  }

  public function pick($quantity = 1) {
    $count = 0;
    $generated = [];
    while($count < $quantity) {
      $num = $this->generate();

      if (sizeof($generated) === $this->maxGeneration) {
        break;
      }

      if (!in_array($num, $generated)) {
        $generated[] = $num;
        $count++;
      }
    }
    return ($quantity === 1) ? $generated[0] : $generated;
  }

  public function generate() {
    return mt_rand($this->min, $this->max);
  }
}

2) Use it:

$randomizer = new Randomizer(0, 999999999);
$number = $randomizer->pick(); // returns 1 number
$numbers = $randomizer->pick(100); // returns array(A, B, C...) of numbers

Upvotes: 0

Related Questions