Search code examples
phprandommatchpreg-match

how can I generate a random 6 digits number with this rule? BY PHP


I have a function called rndgen() generate random 6 digits number that can have zero digit everywhere even beginning of number.

example:

267809

671485

200000

037481

000005

000437

500005

777777

I dont want to generate numbers like 000024 or 240000 or 000005 or 140000 or 500005 or 999999, and there are numbers like 000124 or 245000 or 000555 or 145000 or 511005 or 999887 allowed to generate.

All numbers that have the same digits are not allowed

How can I check this number if more than three digits are the beginning or end of the zero OR more than three zero in the middle of the number, it generate a new number, but if the zeros were at the beginning or end, lower or none could use the same number( BY PHP )?

The Rules I want:

after generating number>

IF ( NUMBER HAS MORE THAN THREE ZERO AT THE BEGINNING OR END OF NUMBER

OR

WHOLE NUMBER HAVE THE SAME DIGITS

OR

NUMBER HAS MORE THAN THREE SAME DIGITS AT THE BEGINNING OR END OF NUMBER

OR

NUMBER HAS MORE THAN THREE ZERO AT IN THE MIDDLE OF NUMBER

)

{ CALL AGAIN rndgen() TO GENERATE NEW RANDOM 6 DIGITS NUMBER }

thanks


Solution

  • It seems you want to reject numbers that have:

    • a digit repeating for more than 3 times without interruption at either end of the number, OR:
    • a zero repeating for more than 3 times without interruption anywhere in the number.

    This you can do with the following regular expression in a preg_match function call:

    ^(\d)\1\1\1|(\d)\2\2\2$|0000
    

    If that matches, then you have a number that should be rejected.

    Here is code to test several numbers:

    $tests = array(
        "000024", "241111", "222225", "143333", "500005", "999999", 
        "000124", "245111", "222555", "145333", "544445", "799997"
    );
    
    foreach($tests as $num) {
        $reject = preg_match("~^(\d)\\1\\1\\1|(\d)\\2\\2\\2$|0000~", $num);
        echo "$num: " . ($reject ? "Not OK" : "OK") . "\n";
    }
    

    The first 6 will print as "Not OK", the other 6 as "OK".

    Your rndgen function could use that as follows:

    function rndgen() {
        do {
            $num = sprintf('%06d', mt_rand(100, 999989));
        } while (preg_match("~^(\d)\\1\\1\\1|(\d)\\2\\2\\2$|0000~", $num));
        return $num;
    }