skip to Main Content

I’m trying to make a "special" string generator, with a custom selection for which characters you want.
shortly in the code when you call this function:

generateRandomString(length, [special characters], [numbers], [lower characters], [upper characters]);

for example:

generateRandomString(5, true, true, true, true);

the code should be max 5 characters, with letters, numbers and special characters… like: fE3%!

but is gives me 5 random string for each bool active so if it 4 I have back 20 characters instead of 5

this is the code, what am I doing wrong?

function generateRandomString($length, $special, $numbers, $upper, $lower)
{
    //$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $characters["special"] = "!%";
    $characters["numbers"] = "01";
    $characters["upper"] = "ABC";
    $characters["lower"] = "abc";
    $randomString = '';
 
    for ($i = 0; $i < $length; $i++)
    {
        if($special)
        {
            $randomString .= $characters["special"][rand(0, strlen($characters["special"]) - 1)];
        }
        if($numbers)
        {
            $randomString .= $characters["numbers"][rand(0, strlen($characters["numbers"]) - 1)];
        }
        if($upper)
        {
            $randomString .= $characters["upper"][rand(0, strlen($characters["upper"]) - 1)];
        }
        if($lower)
        {
            $randomString .= $characters["lower"][rand(0, strlen($characters["lower"]) - 1)];
        }
    }
 
    return $randomString;
}

3

Answers


  1. try to change the for loop to while loop like this :

    function generateRandomString($length, $special, $numbers, $upper, $lower)
        {
            //$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
            $characters["special"] = "!%";
            $characters["numbers"] = "01";
            $characters["upper"] = "ABC";
            $characters["lower"] = "abc";
            $randomString = '';
         
            while(strlen($randomString) <= $length)
            {
                if($special)
                {
                    $randomString .= $characters["special"][rand(0, strlen($characters["special"]) - 1)];
                }
                if($numbers && strlen($randomString) <= $length)
                {
                    $randomString .= $characters["numbers"][rand(0, strlen($characters["numbers"]) - 1)];
                }
                if($upper && strlen($randomString) <= $length)
                {
                    $randomString .= $characters["upper"][rand(0, strlen($characters["upper"]) - 1)];
                }
                if($lower  && strlen($randomString) <= $length)
                {
                    $randomString .= $characters["lower"][rand(0, strlen($characters["lower"]) - 1)];
                }
            }
         
            return $randomString;
        }
    

    Updated :
    (for exemple the length equel to 5)
    for while not breaked if we don’t have 5 steps
    while loop for every step check if the string length not 5
    also checking for every nested condition if the string has equel to 5

    Login or Signup to reply.
  2. You should first build valid characters range based on given parameters, and only then build random string.

    Added validator to ensure that at least one character from each required group exists in random string.

    function generateRandomString($length, $special, $numbers, $upper, $lower)
    {
        //$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $characters["special"] = "!%";
        $characters["numbers"] = implode('', range(0, 9));
        $characters["upper"] = implode('', range('A', 'Z'));
        $characters["lower"] = implode('', range('a', 'z'));
    
        $charactersSet = '';
        $validators = [];
        $randomString = '';
    
        if ($special) {
            $charactersSet .= $characters["special"];
            $validators[] = '/[' . preg_quote($characters["special"]) . ']/';
        }
    
        if ($numbers) {
            $charactersSet .= $characters["numbers"];
            $validators[] = '/d/';
        }
        
        if ($upper) {
            $charactersSet .= $characters["upper"];
            $validators[] = '/[A-Z]/';
        }
    
        if ($lower) {
            $charactersSet .= $characters["lower"];
            $validators[] = '/[a-z]/';
        }
    
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $charactersSet[rand(0, strlen($charactersSet) - 1)];
        }
    
        foreach ($validators as $pattern) {
            if (preg_match($pattern, $randomString) === 0) {
                $randomString = generateRandomString($length, $special, $numbers, $upper, $lower);
    
                break;
            }
        }
    
        return $randomString;
    }
    
    Login or Signup to reply.
  3. This solution picks a random range of characters on each iteration, then picks a random letter from that range of characters.

    function generateRandomString($length, $special, $numbers, $upper, $lower)
    {
        $alphabet = [
            '`~!@#$%^&*()_+-=[]{};':",./<>?',
            '0123456789',
            'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
            'abcdefghijklmnopqrstuvwxyz'
        ];
    
        $allowable = [];
        if ($special)
            $allowable[] = 0;
        if ($numbers)
            $allowable[] = 1;
        if ($upper)
            $allowable[] = 2;
        if ($lower)
            $allowable[] = 3;
    
        $output = '';
    
        for ($i = 0; $i < $length; ++$i) {
            $which = $allowable[array_rand($allowable)];
            $alphabet_size = strlen($alphabet[$which])-1;
            $rand_character = rand(0, $alphabet_size);
            $output .= $alphabet[$which][$rand_character];
        }
    
        return $output;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search