S S
S S

Reputation: 1503

How to generate a unique alphanumeric string with atleast a number?

I need to generate a random string of length 4(Valid string is 1ABC, A12D...). String must contains atleast 1 number and remaining can be [A-Z].

METHOD 1:

protected function generate(int $length = 4): array
{
    $randomString = '';

    $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    for ($i = 0; $i < $length; $i++) {
        $index = random_int(0, strlen($characters) - 1);
        $randomString .= $characters[$index];
    }

    $uppercase = preg_match('@[A-Z]@', $randomString);
    $number = preg_match('@[\d]@', $randomString);


    if (!$uppercase || !$number) {
        $this->generate();
    }

    return $randdomString;
}

METHOD 2:

echo substr(str_shuffle('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'),1, 4);

Most of the time, it is giving me correct answer but some cases, it return me only alphabet values (This is the recent result I get XFJG)

Can anybody please help ?

Upvotes: 0

Views: 210

Answers (1)

The fourth bird
The fourth bird

Reputation: 163372

The OR || will return true if one of both conditions is true, so if there is no number it will pass the if clause.

You could check if both conditions are true instead:

if ($number && $uppercase) {
    // do something with $values
}

Running this again $func(); inside the if clause, will run the function again generating a new string and returns $randomString; from the function.

If you want to return the tested string, you can return the already tested $values

EDIT

If you don't want to return only chars A-Z or only digits, you can update the pattern to match only digit or only chars A-Z using ^\d+$ and ^[A-Z]+$

If one if the conditions is true, then do a recursive call.

protected function generate(int $length = 4): string
{
    $randomString = '';

    $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    for ($i = 0; $i < $length; $i++) {
        $index = random_int(0, strlen($characters) - 1);
        $randomString .= $characters[$index];
    }

    $uppercase = preg_match('@^[A-Z]+$@', $randomString);
    $number = preg_match('@^\d+$@', $randomString);


    if ($uppercase || $number) {
        $randomString = $this->generate();
    }

    return $randomString;
}

See a PHP demo.

Upvotes: 2

Related Questions