ChatGPT解决这个技术问题 Extra ChatGPT

PHP random string generator

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?

My one line solution for generate short string is substr(md5(rand()), 0, 7); good luck ...
@tasmaniski.. Your solution is ok.. But its less randomized! In your example the number of random strings that can be generated is limited by the size of integer. ( 2^32 ) at the max.. In case of the other solution, you can generate ( 62^8 ).. In case, I want larger strings, then number of distinct strings remain at max 2^32, but in the other solution it increases to ( 62^n )..
You forgot to add each new generated character to the string. You're just overwriting it as it is. Should be $randstring .= $characters..
@CaptainLightning Can you please swap out the accepted answer for one of the more secure ones? :)
strlen($characters) => strlen($characters) - 1 - string length starts with 1

s
steadweb

To answer this question specifically, two problems:

$randstring is 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[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}

Output the random string with the call below:

// Echo the random string.
// Optionally, you can give it a desired string length.
echo generateRandomString();

Please note that this generates predictable random strings. If you want to create secure tokens, see this answer.


@FranciscoPresencia, It's better "wasting" an extra variable as of calling an method in the compare condition of an loop.
All that work, why not just something like substr(str_shuffle(MD5(microtime())), 0, 10);?
Thanks for the code, but please change rand() to mt_rand(). I used your method and experienced a ton of collisions with names.
@FranciscoPresencia do you have any idea how horrifically inefficient that is? You are checking the length of a string twice per iteration! The strlen inside the loop should be cached in a variable before entering the loop as well.
This is not a good solution. The strings this generates will be predictable. :(
C
Community

Note: str_shuffle() internally uses rand(), 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. :)


+1 for the shortest answer :). But not the best answer for every use-case. This code will output strings where each character won't appear more than once (thus making it weaker for brute force attacks) and won't output anything longer than 62 characters.
Do not do this, it is extremely weak. The longer you make your random string, the weaker it will be.
Weak it may be, but it's quick and easy. Depending on the use-case, this is fine -- I've used it because I didn't need security or strength; just a quick-fire shuffle. I'm writing a unit test, and this gives me a suitably random input to test with.
@FranciscoPresencia the reason it is not secure is because it never uses the same character twice. That makes it a terrible password generator. Please everyone stop up voting this, it is totally insecure must never be used. As the password gets longer, the number of characters you must test in a brute force gets shorter because you do not bother testing any previously used character.
@FranciscoPresencia: I support your comments about avoiding using this for random passwords. However, I disagree that this answer should not be plus-one'd. I have plus-one'd this option for since it is an effective one-line solution for generating random strings (the original topic of this question).
S
Scott Arciszewski

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)


At the beginning of the function add $keyspace = str_shuffle($keyspace ); for more security
What do you mean by "for more security"? We're already using a secure random number generator.
@JGEstiot Creating securely random strings requires cryptographically secure randomness. Someone searching "how to generate random strings in PHP" is better served by a secure answer than an insecure answer.
@ Scott Arciszewski You do not need to create cryptographically random strings every time you create random strings. The question was about creating randomized strings and this has nothing to do with security. You assumed that the string is going to be used in a security-sensitive context and you add a layer of complexity that deters from the core of the question.
Using random_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.
P
Peter Mortensen

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

Please note that openssl_random_pseudo_bytes() did not use a cryptographically strong algorithm until php 5.6. Related bug: bugs.php.net/bug.php?id=70014
Also note that the smallest string this can make is of length 2. If you pass a byte length of 1 or less to 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.
Proposal to use it as file content that can be opened through 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.
I really like the random_bytes solution for PHP 7, but if you need the string to be a certain number of characters would something like this work? $string = substr(base64_encode(random_bytes($size)), 0, $size);
This is absolutely without a doubt the best solution. Takes up very little space and is super easy to understand.
H
Humphrey

@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


if your string is based on only a random integer, why not just use the random integer? they haystack doesnt get any deeper by hashing it... and by cutting the hash of you actually deminish the little entropy you had to start with.
Keep in mind md5 will result in a 30 character limit and always lowercase characters.
Additionally, rand() shouldn't be used for cryptography. If you're looking to generate a crypographically sound string, use openssl_random_pseudo_bytes.
md5(rand()) only offers 2^32 possible values. This means after, on average, 2^16 random strings you will expect one to repeat.
Well..i would bet the OP is not talking about "securely random strings". This solution is compact, easy and pretty to remember, for the right use cases. And, if you need to take care of possible collisions, why not to prepend/append a timestamp to the random string? :)
r
rjmunro

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.


rand doesn't use /dev/urandom because that is only available in posix like environments and is not portable.
@MacroMan But openssl_random_pseudo_bytes() is portable.
If you want to strip out the extra base64 characters, try this: gist.github.com/zyphlar/7217f566fc83a9633959
This isn't wrong, but I would advise caution in how you discard the unwanted characters. See this pull request on the PHP league's OAuth2 Server, for example.
This is one of the best answers. Pity it doesn't have more support. I would recommend editing your answer for better handling of unwanted characters though.
M
Madan Sapkota

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


This will not generate a string with the given length
getRandomBytes() (all of them, really) only works for even lengths. Other than that, one of the better, less-scary answers here.
@DewiMorgan, I guess any hashing algo generates even length.
Well, it's more that bin2hex() specifically will inevitably return an even number of hex chars. Truncating the output by one char for odd-length cases shouldn't, so far as I can tell, affect the entropy... but I admit it'd add a few extra lines to the code that would be pointless for almost all use-cases.
So $odd=$length%2; $length+=$odd; at the beginning, and return substr(bin2hex($length), $odd); at the end would do the trick... but at the cost of considerable readability. Yours is cleaner and more maintainable, so I'd probably just add a comment about the "only even lengths" caveat if I were to use it, unless it truly mattered.
P
Peter Mortensen

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


sorry to say but when one character gots selected its probability of occuring again is not as high as the other characters still remaining in the pool. no true randomness here...
@TheSurrican - You would be incorrect in that statement. All characters have an equal probability using this algorithm, and thus is truly random. This is ensured by repeating the chrList string $chrRepeatMax, and the magic really happens in str_shuffle which determines the randomness.
This algorithm is clever, but it is based on mt_rand, which generates a deterministic sequence of numbers. The output can be decoded by obtaining or guessing the salt. A true random sequence cannot be decoded into something with less entropy, like a small integer, under any conditions. A good approximation to true randomness is achieved by some systems by generating real-world entropy through such means as measuring how long it takes a person to type or move a mouse. Note that using the system time is not truly random, either, since an attacker can sometimes intercept device timing signals.
str_shuffle is deterministic, not truly random.
Downvote reasons: 1) claims "a true random string" rather than "a pseudorandom string" when mt_rand is not truly random; claims equal probability of character selection, which shows a misunderstanding of statistics. Once the first character is selected from the string, the probability of it's selection for the second is then 9/(10*n) while all other characters are 10/(10*n). This stuff matters: such errors are dangerous in a security context.
P
Peter Mortensen

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.


Caution: mt_rand does not generate cryptographically secure values. For that you should use PHP7's random_int or random_bytes.
D
Davor
function generateRandomString($length = 15)
{
    return substr(sha1(rand()), 0, $length);
}

Tada!


Keep in mind sha1 will result in a 40 character limit and always lowercase characters.
sha1 strings are not random, certain characters will occur more frequently than others. It would be unwise to use this in cases where you genuinely want randomness like for passwords.
@KitSunde - yes, sha isn't random, rand() is random. And sha is perfectly fine for what is needed here. OP doesn't need crypto level of randomness.
@Davor 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.
@KitSunde - it makes literally no difference in the end. That's exactly the definition of overengineering and gold plating.
B
BoltClock

$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))];

4
4 revs

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

The use of the modulo operator % will produce biased output. However, strong +1 for RandomLib. Don't reinvent the wheel.
Yeah, the new random_int() function is nice :D
P
Putnik

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.


I think, that best answer. Thanks!
r
rAthus

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", etc... here it is 5 characters but you can easily change it of course:

$user_password = substr(str_shuffle('abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789'),0,5);

This is perfect to create random ID strings to call later on jquery. IDK if its good practice but this helped me alot, without using a for like the accepted answer...
This method is somewhat "less random" than you might first expect, since there is no chance any character will be used more than once.
You're right @Deji, a five characters length string will "only" have 379 million possible combinations instead of 459 million.
It's actually just under 312 million permutations that your 5-char sub-strings can generate. I'm not sure how to calculate the latter to be honest.
@Deji how did you get to 312M? The songs pics the first from 54 characters, then from the remaining ones, etc, five times, that's 54*53*52*51*50 = 379.501.200 possible combinations.
P
Punit Gajjar

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()));
?>

B
BassMHL

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()


a
artnikpro

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

"Should not be considered sufficient for cryptography, etc." This should be strongly emphasized.
M
Mr. Coderx
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


V
Vasil Kulakov

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

Р
Руслан Ибрагимов
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;
}

This is not portable; if you try to run this in any non-posix environment, it will cause a fatal error.
u
userlond

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.


s
sxn

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

good solution i made this in a different way using the same technique thank you mate
Works for what I needed to achieve, many thanks
m
mike_t
/**
 * @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/


P
Peter Mortensen

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


finally a truly random solution not some bloated hash of a 32 bit random integer or a shuffled string...
theres just one issue: numbers are as likely to occur as characters, which is not as random as i would love to have it. anyaway +1 for the best solution on this page. tweak that and its perfect.
tweak... like this? rand(0, 57-48+122-97)<57-48?...:... ? :)
P
Peter Mortensen

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

md5(rand()) is a horrendously insecure way to generate a random number.
a string with X length and some uniqueness is the intent. true randomness is not the intent.
P
Peter Mortensen
function randomString($length = 5) {
    return substr(str_shuffle(implode(array_merge(range('A','Z'), range('a','z'), range(0,9)))), 0, $length);
}

P
Peter Mortensen

The edited version of the function works fine, but there is just one issue I found: You used the wrong character to enclose $characters, so the ’ character is sometimes part of the random string that is generated.

To fix this, change:

$characters = ’0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;

to:

$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

This way only the enclosed characters are used, and the ’ character will never be a part of the random string that is generated.


M
MRMP
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);

R
RKaneKnight

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

J
James McCracken

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.


Of course, 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.
so what you are basically doing is shuffling around a 32 bit integer. not a lot of entropy here...
An attacker can guess the value returned by time() (it's only a timestamp), it's a weak source of randomness.