How to create a random string using PHP?

PhpStringRandom

Php Problem Overview


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.

Php Solutions


Solution 1 - Php

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].

Solution 2 - Php

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.

Solution 3 - Php

My favorite:

 echo substr(md5(rand()), 0, 7);

Solution 4 - Php

So, let me start off by saying USE A LIBRARY. Many exist:

The core of the problem is almost every answer in this page is susceptible to attack. mt_rand(), rand(), lcg_value() and uniqid() are all vulnerable to attack.

A good system will use /dev/urandom from the filesystem, or mcrypt_create_iv() (with MCRYPT_DEV_URANDOM) or openssl_pseudo_random_bytes(). Which all of the above do. PHP 7 will come with two new functions random_bytes($len) and random_int($min, $max) that are also safe.

Be aware that most of those functions (except random_int()) return "raw strings" meaning they can contain any ASCII character from 0 - 255. If you want a printable string, I'd suggest running the result through base64_encode().

Solution 5 - Php

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.

Solution 6 - Php

A better and updated version of @taskamiski's excellent answer:

Better version, using mt_rand() instead of rand():

echo md5(mt_rand()); // 32 char string = 128bit

Even better, for longer strings, using the hash() function that allows to select hashing algorithmns:

echo hash('sha256', mt_rand()); // 64 char string
echo hash('sha512', mt_rand()); // 128 char string

If you want to cut the result down to let's say 50 chars, do it like this:

echo substr(hash('sha256', mt_rand()), 0, 50); // 50 char string

Solution 7 - Php

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);   
}

Solution 8 - Php

this will generate random string

function generateRandomString($length=10) {
	$original_string = array_merge(range(0,9), range('a','z'), range('A', 'Z'));
	$original_string = implode("", $original_string);
	return substr(str_shuffle($original_string), 0, $length);
}
echo generateRandomString(6);

Solution 9 - Php

Most aspects of this have already been discussed, but i'd recommend a slight update: If you are using this for retail usage, I would avoid the domain ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789

and instead use: ABCDEFGHJKMNPQRSTUVWXY3456789

Granted, you end up with far fewer characters, but it saves a great deal of hassle, as customers cannot mistake 0 for O, or 1 for l or 2 for Z. Also, you can do an UPPER on the input and customers can then enter upper or lower case letters -- that is also sometimes confusing since they can look similar.

Solution 10 - Php

I think I will add my contribution here as well.

function random_string($length) {
    $bytes_1 = openssl_random_pseudo_bytes($length);
    $hex_1 = bin2hex($bytes_1);
    $random_numbers = substr(sha1(rand()), 0, $length);
    $bytes_2 = openssl_random_pseudo_bytes($length);
    $hex_2 = bin2hex($bytes_2);
    $combined_chars = $hex_1 . $random_numbers . $hex_2;
    $chars_crypted = hash('sha512', $combined_chars);

    return $chars_crypted;
}

Thanks

Solution 11 - Php

What do you need a random string for?

Is this going to be used for anything remotely analogous to a password?

If your random string requires any security properties at all, you should use PHP 7's random_int() function instead of all the insecure mt_rand() answers in this thread.

/**
 * Generate a random string
 * 
 * @link https://paragonie.com/b/JvICXzh_jhLyt4y3
 *
 * @param int $length - How long should our random string be?
 * @param string $charset - A string of all possible characters to choose from
 * @return string
 */
function random_str($length = 32, $charset = 'abcdefghijklmnopqrstuvwxyz')
{
    // Type checks:
    if (!is_numeric($length)) {
        throw new InvalidArgumentException(
            'random_str - Argument 1 - expected an integer'
        );
    }
    if (!is_string($charset)) {
        throw new InvalidArgumentException(
            'random_str - Argument 2 - expected a string'
        );
    }

    if ($length < 1) {
        // Just return an empty string. Any value < 1 is meaningless.
        return '';
    }
    // This is the maximum index for all of the characters in the string $charset
    $charset_max = strlen($charset) - 1;
    if ($charset_max < 1) {
        // Avoid letting users do: random_str($int, 'a'); -> 'aaaaa...'
        throw new LogicException(
            'random_str - Argument 2 - expected a string at least 2 characters long'
        );
    }
    // Now that we have good data, this is the meat of our function:
    $random_str = '';
    for ($i = 0; $i < $length; ++$i) {
        $r = random_int(0, $charset_max);
        $random_str .= $charset[$r];
    }
    return $random_str;
}

If you aren't on PHP 7 yet (which is probably the case, as it hasn't been released as of this writing), then you'll want paragonie/random_compat, which is a userland implementation of random_bytes() and random_int() for PHP 5 projects.

For security contexts, always use random_int(), not rand(), mt_rand(), etc. See ircmaxell's answer as well.

Solution 12 - Php

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

Solution 13 - Php

// @author http://codeascraft.etsy.com/2012/07/19/better-random-numbers-in-php-using-devurandom/                                                
function devurandom_rand($min = 0, $max = 0x7FFFFFFF)
{
    $diff = $max - $min;
    if ($diff < 0 || $diff > 0x7FFFFFFF) {
		throw new RuntimeException('Bad range');
    }
    $bytes = mcrypt_create_iv(4, MCRYPT_DEV_URANDOM);
    if ($bytes === false || strlen($bytes) != 4) {
        throw new RuntimeException('Unable to get 4 bytes');
    }
    $ary = unpack('Nint', $bytes);
    $val = $ary['int'] & 0x7FFFFFFF; // 32-bit safe                           
    $fp = (float) $val / 2147483647.0; // convert to [0,1]                          
    return round($fp * $diff) + $min;
}

function build_token($length = 60, $characters_map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') {
	$map_length = mb_strlen($characters_map)-1;
	$token = '';
	while ($length--) {
		$token .= mb_substr($characters_map, devurandom_rand(0,$map_length),1);
	}
	return $token;
}

This will work only in UNIX environment where PHP is compiled with mcrypt.

Solution 14 - Php

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.

Solution 15 - Php

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.

Solution 16 - Php

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

Solution 17 - Php

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.

Solution 18 - Php

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

Solution 19 - Php

This builds on Gumbo's solution by adding functionality to list a set of characters to be skipped in the base character set. The random string selects characters from $base_charset which do not also appear in $skip_charset.

/* Make a random string of length using characters from $charset, excluding $skip_chars.
 * @param length (integer) length of return value
 * @param skip_chars (string) characters to be excluded from $charset
 * @param charset (string) characters of posibilities for characters in return val
 * @return (string) random string of length $length    */
function rand_string(
        $length, 
        $skip_charset = '', 
        $base_charset='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'){
  $skip_len = strlen($skip_charset);
  for ($i = 0; $i<$skip_len; $i++){
    $base_charset = str_replace($skip_charset[$i], '', $base_charset);
  }
  cvar_dump($base_charset, '$base_charset after replace');
  $str = '';
  $count = strlen($base_charset);
  while ($length--) {
    $str .= $base_charset[mt_rand(0, $count - 1)];
  }
  return $str;
}

Here are some usage examples. The first two examples use the default value for $base_charset. The last example explicitly defines $base_charset.

echo rand_string(15, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');
//  470620078953298
echo rand_string(8, 'abcdefghijklmnopqrstuvwxyz0123456789');
//  UKLIHOTFSUZMFPU
echo rand_string(15, 'def', 'abcdef');
//  cbcbbccbabccaba

Solution 20 - Php

well, I was looking for a solution, and I kindda used @Chad Birch's solution merged with @Gumbo's one. This is what I came up with:

function get_random_string($length, $valid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456790!·$%&/()=?¿¡',.-;:+*`+´ç")
{
	$random_string = "";
    $num_valid_chars = strlen($valid_chars);
    for ($i = 0; $i < $length; $i++, $random_string .= $valid_chars[mt_rand(1, $num_valid_chars)-1]);
    return $random_string;
}

I think comments are pretty much unnecesary since the answers I used to build up this one are already thoroughly commented. Cheers!

Solution 21 - Php

If you're not concerned about time, memory, or cpu efficiency, and if your system can handle it, why not give this algorithm a try?!

function randStr($len, $charset = 'abcdABCD0123') {
    $out = '';
    $str = array();

    for ($i = 0; $i < PHP_INT_MAX; $i++) {
        $str[$i] = $charset;

        shuffle($str);
        $charset .= implode($charset, $str);
        $charset = str_shuffle($charset);
    }

    $str = array_flip($str);
    $str = array_keys($str);

    for ($i = 0; $i < PHP_INT_MAX; $i++) {
        shuffle($str);
    }

    $str = implode('', $str);

    for ($i = 0; $i < strlen($str); $i++) {
        $index = mt_rand(1, strlen($str));
        $out .= $str[$index - 1];
    }

    for ($i = 0; $i < PHP_INT_MAX; $i++) {
        $out = str_shuffle($out);
    }

    return substr($out, 0, $len);
}

Maybe this will read better if it uses recursion, but I'm not sure if PHP uses tail recursion or not...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKeith DoneganView Question on Stackoverflow
Solution 1 - PhpGumboView Answer on Stackoverflow
Solution 2 - PhpChad BirchView Answer on Stackoverflow
Solution 3 - PhptasmaniskiView Answer on Stackoverflow
Solution 4 - PhpircmaxellView Answer on Stackoverflow
Solution 5 - PhpnamehtView Answer on Stackoverflow
Solution 6 - PhpSliqView Answer on Stackoverflow
Solution 7 - PhpImranView Answer on Stackoverflow
Solution 8 - PhpAkhilraj N SView Answer on Stackoverflow
Solution 9 - PhpCoderOfTheNightView Answer on Stackoverflow
Solution 10 - PhpzeeksView Answer on Stackoverflow
Solution 11 - PhpScott ArciszewskiView Answer on Stackoverflow
Solution 12 - PhpToskanView Answer on Stackoverflow
Solution 13 - PhpGajusView Answer on Stackoverflow
Solution 14 - PhpDarioView Answer on Stackoverflow
Solution 15 - PhpAlessandroView Answer on Stackoverflow
Solution 16 - PhpOscar GarciaView Answer on Stackoverflow
Solution 17 - PhpAlphaView Answer on Stackoverflow
Solution 18 - PhpJosh CurrenView Answer on Stackoverflow
Solution 19 - PhpsteampoweredView Answer on Stackoverflow
Solution 20 - PhptfrascaroliView Answer on Stackoverflow
Solution 21 - Phprodrigo-silveiraView Answer on Stackoverflow