I'm trying to create a randomized string in PHP, and I get absolutely no output with this:
<?php
function RandomString()
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randstring = '';
for ($i = 0; $i < 10; $i++) {
$randstring = $characters[rand(0, strlen($characters))];
}
return $randstring;
}
RandomString();
echo $randstring;
What am I doing wrong?
62 Answers 62
To answer this question specifically, two problems:
$randstringis not in scope when you echo it.- The characters are not getting concatenated together in the loop.
Here's a code snippet with the corrections:
function generateRandomString($length = 10) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[random_int(0, $charactersLength - 1)];
}
return $randomString;
}
Output the random string with the call below:
// Echo the random string.
echo generateRandomString();
// Optionally, you can give it a desired string length.
echo generateRandomString(64);
Please note that previous version of this answer used
rand()instead ofrandom_int()and therefore generated predictable random strings. So it was changed to be more secure, following advice from this answer.
17 Comments
substr(str_shuffle(MD5(microtime())), 0, 10);?rand() to mt_rand(). I used your method and experienced a ton of collisions with names.Note:
str_shuffle()internally usesrand(), which is unsuitable for cryptography purposes (e.g. generating random passwords). You want a secure random number generator instead. It also doesn't allow characters to repeat.
One more way.
UPDATED (now this generates any length of string):
function generateRandomString($length = 10) {
return substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,$length);
}
echo generateRandomString(); // OR: generateRandomString(24)
That's it. :)
20 Comments
There are a lot of answers to this question, but none of them leverage a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG).
The simple, secure, and correct answer is to use RandomLib and don't reinvent the wheel.
For those of you who insist on inventing your own solution, PHP 7.0.0 will provide random_int() for this purpose; if you're still on PHP 5.x, we wrote a PHP 5 polyfill for random_int() so you can use the new API even before you upgrade to PHP 7.
Safely generating random integers in PHP isn't a trivial task. You should always check with your resident StackExchange cryptography experts before you deploy a home-grown algorithm in production.
With a secure integer generator in place, generating a random string with a CSPRNG is a walk in the park.
Creating a Secure, Random String
/**
* Generate a random string, using a cryptographically secure
* pseudorandom number generator (random_int)
*
* This function uses type hints now (PHP 7+ only), but it was originally
* written for PHP 5 as well.
*
* For PHP 7, random_int is a PHP core function
* For PHP 5.x, depends on https://github.com/paragonie/random_compat
*
* @param int $length How many characters do we want?
* @param string $keyspace A string of all possible characters
* to select from
* @return string
*/
function random_str(
int $length = 64,
string $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
): string {
if ($length < 1) {
throw new \RangeException("Length must be a positive integer");
}
$pieces = [];
$max = mb_strlen($keyspace, '8bit') - 1;
for ($i = 0; $i < $length; ++$i) {
$pieces []= $keyspace[random_int(0, $max)];
}
return implode('', $pieces);
}
Usage:
$a = random_str(32);
$b = random_str(8, 'abcdefghijklmnopqrstuvwxyz');
$c = random_str();
Demo: https://3v4l.org/IMJGF (Ignore the PHP 5 failures; it needs random_compat)
17 Comments
$keyspace = str_shuffle($keyspace ); for more securityrandom_int() instead of rand() or mt_rand() adds no complexity for the developer. At the same time, it gives them greater security. People who come to StackOverflow looking for quick solutions might not know if the thing they're building needs to be secure or not. If we give them secure-by-default answers, they create a more secure Internet even if, from their perspective, it's totally accidental. Why you would oppose this goal is a mystery to me.This creates a 20 character long hexadecimal string:
$string = bin2hex(openssl_random_pseudo_bytes(10)); // 20 chars
In PHP 7 (random_bytes()):
$string = base64_encode(random_bytes(10)); // ~14 characters, includes /=+
// or
$string = substr(str_replace(['+', '/', '='], '', base64_encode(random_bytes(32))), 0, 32); // 32 characters, without /=+
// or
$string = bin2hex(random_bytes(10)); // 20 characters, only 0-9a-f
8 Comments
openssl_random_pseudo_bytes() did not use a cryptographically strong algorithm until php 5.6. Related bug: bugs.php.net/bug.php?id=70014 openssl_random_pseudo_bytes() you will get nothing back. Also, note that when using bin2hex(openssl_random_pseudo_bytes($length / 2)) since you are working with integers, it will automatically remove the modulo and will use the next lowest multiple of 2. So, $length = 19 will produce a string of length 18.fgets($fp, 1024) and every file editor that has problems with very long lines: function string_rand($len, $split="\n") { return substr(chunk_split(bin2hex(openssl_random_pseudo_bytes(ceil($len / 2))), 1023, $split), 0, $len); } Set $split to null if it should return a one-liner. By that you can use it for both cases.$string = substr(base64_encode(random_bytes($size)), 0, $size);@tasmaniski: your answer worked for me. I had the same problem, and I would suggest it for those who are ever looking for the same answer. Here it is from @tasmaniski:
<?php
$random = substr(md5(mt_rand()), 0, 7);
echo $random;
?>
Here is a youtube video showing us how to create a random number
7 Comments
md5 will result in a 30 character limit and always lowercase characters.md5(rand()) only offers 2^32 possible values. This means after, on average, 2^16 random strings you will expect one to repeat.Depending on your application (I wanted to generate passwords), you could use
$string = base64_encode(openssl_random_pseudo_bytes(30));
Being base64, they may contain = or - as well as the requested characters. You could generate a longer string, then filter and trim it to remove those.
openssl_random_pseudo_bytes seems to be the recommended way way to generate a proper random number in php. Why rand doesn't use /dev/random I don't know.
7 Comments
openssl_random_pseudo_bytes() is portable.PHP 7+ Generate cryptographically secure random bytes using random_bytes function.
$bytes = random_bytes(16);
echo bin2hex($bytes);
Possible output
da821217e61e33ed4b2dd96f8439056c
PHP 5.3+ Generate pseudo-random bytes using openssl_random_pseudo_bytes function.
$bytes = openssl_random_pseudo_bytes(16);
echo bin2hex($bytes);
Possible output
e2d1254506fbb6cd842cd640333214ad
The best use case could be
function getRandomBytes($length = 16)
{
if (function_exists('random_bytes')) {
$bytes = random_bytes($length / 2);
} else {
$bytes = openssl_random_pseudo_bytes($length / 2);
}
return bin2hex($bytes);
}
echo getRandomBytes();
Possible output
ba8cc342bdf91143
6 Comments
Here is a simple one-liner that generates a true random string without any script level looping or use of OpenSSL libraries.
echo substr(str_shuffle(str_repeat('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', mt_rand(1,10))), 1, 10);
To break it down so the parameters are clear
// Character List to Pick from
$chrList = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
// Minimum/Maximum times to repeat character List to seed from
$chrRepeatMin = 1; // Minimum times to repeat the seed string
$chrRepeatMax = 10; // Maximum times to repeat the seed string
// Length of Random String returned
$chrRandomLength = 10;
// The ONE LINE random command with the above variables.
echo substr(str_shuffle(str_repeat($chrList, mt_rand($chrRepeatMin,$chrRepeatMax))), 1, $chrRandomLength);
This method works by randomly repeating the character list, then shuffles the combined string, and returns the number of characters specified.
You can further randomize this, by randomizing the length of the returned string, replacing $chrRandomLength with mt_rand(8, 15) (for a random string between 8 and 15 characters).
10 Comments
A better way to implement this function is:
function RandomString($length) {
$keys = array_merge(range(0,9), range('a', 'z'));
$key = "";
for($i=0; $i < $length; $i++) {
$key .= $keys[mt_rand(0, count($keys) - 1)];
}
return $key;
}
echo RandomString(20);
mt_rand is more random according to this and this in PHP 7. The rand function is an alias of mt_rand.
1 Comment
mt_rand does not generate cryptographically secure values. For that you should use PHP7's random_int or random_bytes.function generateRandomString($length = 15)
{
return substr(sha1(rand()), 0, $length);
}
Tada!
8 Comments
sha1 will result in a 40 character limit and always lowercase characters.rant() being random doesn't matter when sha isn't evenly distributed. If you randomly select from an uneven distribution you get the exact same uneven distribution. It's not "crypto level" randomness I'm highlighting, if that was the case you shouldn't be using rand() either. It takes minimal effort to pluck from an even distribution like in the accepted answer and it's as random as rand() is which is reasonably so.Here's my simple one line solution to generate a use friendly random password, excluding the characters that lookalike such as "1" and "l", "O" and "0", "5" and "S", etc... this example generates 5 characters string but you can easily change it by modifyling the last variable:
$user_password = substr(str_shuffle('abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRTUVWXYZ2346789'),0,5);
It's obviously not the most secure solution as it has a limited amount of different characters and each can only be used once in the output, but a 5 character long string will still allow over 311 million combinations, and a 7 character long over 674 billion combinations, etc, so it's still an elegent, user-friendly, super light and easy to use method for non-critical uses.
7 Comments
$randstring in the function scope is not the same as the scope where you call it. You have to assign the return value to a variable.
$randstring = RandomString();
echo $randstring;
Or just directly echo the return value:
echo RandomString();
Also, in your function you have a little mistake. Within the for loop, you need to use .= so each character gets appended to the string. By using = you are overwriting it with each new character instead of appending.
$randstring .= $characters[rand(0, strlen($characters))];
Comments
First, you define the alphabet you want to use:
$alphanum = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$special = '~!@#$%^&*(){}[],./?';
$alphabet = $alphanum . $special;
Then, use openssl_random_pseudo_bytes() to generate proper random data:
$len = 12; // length of password
$random = openssl_random_pseudo_bytes($len);
Finally, you use this random data to create the password. Because each character in $random can be chr(0) until chr(255), the code uses the remainder after division of its ordinal value with $alphabet_length to make sure only characters from the alphabet are picked (note that doing so biases the randomness):
$alphabet_length = strlen($alphabet);
$password = '';
for ($i = 0; $i < $len; ++$i) {
$password .= $alphabet[ord($random[$i]) % $alphabet_length];
}
Alternatively, and generally better, is to use RandomLib and SecurityLib:
use SecurityLib\Strength;
$factory = new RandomLib\Factory;
$generator = $factory->getGenerator(new Strength(Strength::MEDIUM));
$password = $generator->generateString(12, $alphabet);
2 Comments
% will produce biased output. However, strong +1 for RandomLib. Don't reinvent the wheel.I've tested performance of most popular functions there, the time which is needed to generate 1'000'000 strings of 32 symbols on my box is:
2.5 $s = substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,32);
1.9 $s = base64_encode(openssl_random_pseudo_bytes(24));
1.68 $s = bin2hex(openssl_random_pseudo_bytes(16));
0.63 $s = base64_encode(random_bytes(24));
0.62 $s = bin2hex(random_bytes(16));
0.37 $s = substr(md5(rand()), 0, 32);
0.37 $s = substr(md5(mt_rand()), 0, 32);
Please note it is not important how long it really was but which is slower and which one is faster so you can select according to your requirements including cryptography-readiness etc.
substr() around MD5 was added for sake of accuracy if you need string which is shorter than 32 symbols.
For sake of answer: the string was not concatenated but overwritten and result of the function was not stored.
3 Comments
substr(md5(mt_rand()), 0, 32) since md5 always produces a 32 character string?function gen_uid($l=5){
return substr(str_shuffle("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), 10, $l);
}
echo gen_uid();
Default Value[5]: WvPJz
echo gen_uid(30);
Value[30]: cAiGgtf1lDpFWoVwjykNKXxv6SC4Q2
Comments
Short Methods..
Here are some shortest method to generate the random string
<?php
echo $my_rand_strng = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), -15);
echo substr(md5(rand()), 0, 7);
echo str_shuffle(MD5(microtime()));
?>
Comments
One very quick way is to do something like:
substr(md5(rand()),0,10);
This will generate a random string with the length of 10 chars. Of course, some might say it's a bit more heavy on the computation side, but nowadays processors are optimized to run md5 or sha256 algorithm very quickly. And of course, if the rand() function returns the same value, the result will be the same, having a 1 / 32767 chance of being the same. If security's the issue, then just change rand() to mt_rand()
Comments
Starting from php8.3 you can do this:
$rng = new Random\Randomizer();
$crockfordAlphabet = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
$rng->getBytesFromString($crockfordAlphabet, 10); // "5YH837JSJT"
Comments
Helper function from Laravel 5 framework
/**
* Generate a "random" alpha-numeric string.
*
* Should not be considered sufficient for cryptography, etc.
*
* @param int $length
* @return string
*/
function str_random($length = 16)
{
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
return substr(str_shuffle(str_repeat($pool, $length)), 0, $length);
}
1 Comment
Since php7, there is the random_bytes functions. https://www.php.net/manual/ru/function.random-bytes.php So you can generate a random string like that
<?php
$bytes = random_bytes(5);
var_dump(bin2hex($bytes));
?>
Comments
from the yii2 framework
/**
* Generates a random string of specified length.
* The string generated matches [A-Za-z0-9_-]+ and is transparent to URL-encoding.
*
* @param int $length the length of the key in characters
* @return string the generated random key
*/
function generateRandomString($length = 10) {
$bytes = random_bytes($length);
return substr(strtr(base64_encode($bytes), '+/', '-_'), 0, $length);
}
1 Comment
function rndStr($len = 64) {
$randomData = file_get_contents('/dev/urandom', false, null, 0, $len) . uniqid(mt_rand(), true);
$str = substr(str_replace(array('/','=','+'),'', base64_encode($randomData)),0,$len);
return $str;
}
1 Comment
Here is how I am doing it to get a true unique random key:
$Length = 10;
$RandomString = substr(str_shuffle(md5(time())), 0, $Length);
echo $RandomString;
You can use time() since it is a Unix timestamp and is always unique compared to other random mentioned above. You can then generate the md5sum of that and take the desired length you need from the generated MD5 string. In this case I am using 10 characters, and I could use a longer string if I would want to make it more unique.
I hope this helps.
4 Comments
time() is far from unique: it'll return the same value again and again until current second ends. What really provides some randomness here is str_shuffle()—the rest of the code only reduces the sample to pick chars from.time() (it's only a timestamp), it's a weak source of randomness./**
* @param int $length
* @param string $abc
* @return string
*/
function generateRandomString($length = 10, $abc = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
{
return substr(str_shuffle($abc), 0, $length);
}
Source from http://www.xeweb.net/2011/02/11/generate-a-random-string-a-z-0-9-in-php/
Comments
Another one-liner, which generates a random string of 10 characters with letters and numbers. It will create an array with range (adjust the second parameter to set the size), loops over this array and assigns a random ASCII character (range 0-9 or a-z), then implodes the array to get a string.
$str = implode('', array_map(function () { return chr(rand(0, 1) ? rand(48, 57) : rand(97, 122)); }, range(0, 9)));
Note: this only works in PHP 5.3 and later
Comments
One liner.
It is fast for huge strings with some uniqueness.
function random_string($length){
return substr(str_repeat(md5(rand()), ceil($length/32)), 0, $length);
}
2 Comments
md5(rand()) is a horrendously insecure way to generate a random number.function randomString($length = 5) {
return substr(str_shuffle(implode(array_merge(range('A','Z'), range('a','z'), range(0,9)))), 0, $length);
}
Comments
This one was taken from adminer sources:
/** Get a random string
* @return string 32 hexadecimal characters
*/
function rand_string() {
return md5(uniqid(mt_rand(), true));
}
Adminer, database management tool written in PHP.
Update 2025:
Should not be considered sufficient for cryptography. See @IMSoP comment below.
2 Comments
uniqid is mostly based on the time, md5 is not random at all, and mt_rand can be seeded and has known patterns.function generateRandomString($length = 10, $hasNumber = true, $hasLowercase = true, $hasUppercase = true): string
{
$string = '';
if ($hasNumber)
$string .= '0123456789';
if ($hasLowercase)
$string .= 'abcdefghijklmnopqrstuvwxyz';
if ($hasUppercase)
$string .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
return substr(str_shuffle(str_repeat($x = $string, ceil($length / strlen($x)))), 1, $length);
}
and use:
echo generateRandomString(32);
Comments
I liked the last comment which used openssl_random_pseudo_bytes, but it wasn't a solution for me as I still had to remove the characters I didn't want, and I wasn't able to get a set length string. Here is my solution...
function rndStr($len = 20) {
$rnd='';
for($i=0;$i<$len;$i++) {
do {
$byte = openssl_random_pseudo_bytes(1);
$asc = chr(base_convert(substr(bin2hex($byte),0,2),16,10));
} while(!ctype_alnum($asc));
$rnd .= $asc;
}
return $rnd;
}
strlen($characters)=>strlen($characters) - 1- string length starts with 1php -r "echo sha1(rand());"