How to create a random string using PHP?

Viewed 96025

I know that the rand function in PHP generates random integers, but what is the best way to generate a random string such as:

Original string, 9 chars

$string = 'abcdefghi';

Example random string limiting to 6 chars

$string = 'ibfeca';

UPDATE: I have found tons of these types of functions, basically I'm trying to understand the logic behind each step.

UPDATE: The function should generate any amount of chars as required.

Please comment the parts if you reply.

22 Answers

If you want to allow repetitive occurences of characters, you can use this function:

function randString($length, $charset='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')
{
    $str = '';
    $count = strlen($charset);
    while ($length--) {
        $str .= $charset[mt_rand(0, $count-1)];
    }
    return $str;
}

The basic algorithm is to generate <length> times a random number between 0 and <number of characters> − 1 we use as index to pick a character from our set and concatenate those characters. The 0 and <number of characters> − 1 bounds represent the bounds of the $charset string as the first character is addressed with $charset[0] and the last with $charset[count($charset) - 1].

Well, you didn't clarify all the questions I asked in my comment, but I'll assume that you want a function that can take a string of "possible" characters and a length of string to return. Commented thoroughly as requested, using more variables than I would normally, for clarity:

function get_random_string($valid_chars, $length)
{
    // start with an empty random string
    $random_string = "";

    // count the number of chars in the valid chars string so we know how many choices we have
    $num_valid_chars = strlen($valid_chars);

    // repeat the steps until we've created a string of the right length
    for ($i = 0; $i < $length; $i++)
    {
        // pick a random number from 1 up to the number of valid chars
        $random_pick = mt_rand(1, $num_valid_chars);

        // take the random character out of the string of valid chars
        // subtract 1 from $random_pick because strings are indexed starting at 0, and we started picking at 1
        $random_char = $valid_chars[$random_pick-1];

        // add the randomly-chosen char onto the end of our string so far
        $random_string .= $random_char;
    }

    // return our finished random string
    return $random_string;
}

To call this function with your example data, you'd call it something like:

$original_string = 'abcdefghi';
$random_string = get_random_string($original_string, 6);

Note that this function doesn't check for uniqueness in the valid chars passed to it. For example, if you called it with a valid chars string of 'AAAB', it would be three times more likely to choose an A for each letter as a B. That could be considered a bug or a feature, depending on your needs.

function generate_random_string($name_length = 8) {
    $alpha_numeric = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    return substr(str_shuffle(str_repeat($alpha_numeric, $name_length)), 0, $name_length);
}

Updated the code as per mzhang's great suggestion in the comments below.

Joining characters at the end should be more efficient that repeated string concatenation.

Edit #1: Added option to avoid character repetition.

Edit #2: Throws exception to avoid getting into infinite loop if $norepeat is selected and $len is greater than the charset to pick from.

Edit #3: Uses array keys to store picked random characters when $norepeat is selected, as associative array key lookup is faster than linearly searching the array.

function rand_str($len, $norepeat = true)
{
    $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    $max = strlen($chars) - 1;

    if ($norepeat && len > $max + 1) {
        throw new Exception("Non repetitive random string can't be longer than charset");
    }

    $rand_chars = array();

    while ($len) {
        $picked = $chars[mt_rand(0, $max)];

        if ($norepeat) {
            if (!array_key_exists($picked, $rand_chars)) {
                $rand_chars[$picked] = true;
                $len--;
            }
        }
        else {
            $rand_chars[] = $picked;
            $len--;
        }
    }

    return implode('', $norepeat ? array_keys($rand_chars) : $rand_chars);   
}

built on top of https://stackoverflow.com/a/853898/533426

but with php 7 cryptographically secure random function and lower AND upper case alphabet

function random($length = 8){
            $valid_chars ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

            // start with an empty random string
            $random_string = "";

            // count the number of chars in the valid chars string so we know how many choices we have
            $num_valid_chars = strlen($valid_chars);

            // repeat the steps until we've created a string of the right length
            for ($i = 0; $i < $length; $i++)
            {
                // pick a random number from 1 up to the number of valid chars
                $random_pick = random_int(1, $num_valid_chars);

                // take the random character out of the string of valid chars
                // subtract 1 from $random_pick because strings are indexed starting at 0, and we started picking at 1
                $random_char = $valid_chars[$random_pick-1];

                // add the randomly-chosen char onto the end of our string so far
                $random_string .= $random_char;
            }

            // return our finished random string
            return $random_string;
    }

//example output XjdXHakZ, yBG8hpZG, L6jg4FpK

Do you want to create your password by a random permutation of the original letters? Should it just contain unique characters?

Use rand to choose random letters by index.

This is an old question but I want try to post my solution... I always use this my function to generate a custom random alphanumeric string...

<?php
  function random_alphanumeric($length) {
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345689';
    $my_string = '';
    for ($i = 0; $i < $length; $i++) {
      $pos = mt_rand(0, strlen($chars) -1);
      $my_string .= substr($chars, $pos, 1);
    }
    return $my_string;
  }
  $test = random_alphanumeric(50); // 50 characters
  echo $test;
?>

test: UFOruSSTCPIqxTRIIMTRkqjOGidcVlhYaS9gtwttxglheVugFM

if you need two or more unique strings you can use this trick...

$string_1 = random_alphanumeric(50);
$string_2 = random_alphanumeric(50);
while ($string_1 == $string_2) {
  $string_1 = random_alphanumeric(50);
  $string_2 = random_alphanumeric(50);
  if ($string_1 != $string_2) {
     break;
  }
}
echo $string_1;
echo "<br>\n";
echo $string_2;

$string_1: tMYicqLCHEvENwYbMUUVGTfkROxKIekEB2YXx5FHyVByp3mlJO

$string_2: XdMNJYpMlFRKFDlF6GhVn6jsBVNQ1BCCevj8yK2niFOgpDI2MU

I hope this help.

echo substr(bin2hex(random_bytes(14)), 0, $length);

this code gets a random bytes, that are converted from binary to hexadecimal, and then takes a substring of this hexadecimal string, as long you puts in $length variable

Try this

Simple enough!

function RandomFromCharset($charset,$length) 
{

$characters = $charset; // your existing charset / defined string
    $charactersLength = strlen($characters);
    $random_from_charset = '';
    for ($i = 0; $i < $length; $i++) 
    {
        $random_from_charset.= $characters[rand(0, $charactersLength - 1)];
    }

return random_from_charset;
}

Call the function as follows

RandomFromCharset($charset,$length);

where $length will be length of random string you want (this can be predefined also in the function as RandomFromCharset(charset,$length=10) ) to generate and $charset will be your existing string to which you want to restrict the characters.

One approach is to generate an md5 from a random number and extract the number of characters you want:

<?php 
    $random = substr(md5(mt_rand()), 0, 7);
    echo $random;
?>

mt_rand will generate a random number, md5 will create a 32 character string (containing both letters and numbers) and, in this example, we're extracting the first 7 characters of text.

you could make an array of characters then use rand() to pick a letter from the array and added it to a string.

$letters = array( [0] => 'a' [1] => 'b' [2] => 'c' [3] => 'd' ... [25] = 'z');

$lengthOfString = 10;
$str = '';

while( $lengthOfString-- )
{
   $str .= $letters[rand(0,25)];
}
echo $str;

*note that this does allow repeat characters

Related