40

I am looking for the shortest way to generate random/unique strings and for that I was using the following two:

$cClass = sha1(time());

or

$cClass = md5(time());

However, I need the string to begin with a letter, I was looking at base64 encoding but that adds == at the end and then I would need to get rid of that.

What would be the best way to achieve this with one line of code?


Update:

PRNDL came up with a good suggestions which I ended up using it but a bit modified

echo substr(str_shuffle(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ),0, 1) . substr(str_shuffle(aBcEeFgHiJkLmNoPqRstUvWxYz0123456789),0, 31)

Would yield 32 characters mimicking the md5 hash but it would always product the first char an alphabet letter, like so;

solution 1

However, Uours really improved upon and his answer;

substr(str_shuffle("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 1).substr(md5(time()),1);

is shorter and sweeter

The other suggestion by Anonymous2011 was very awesome but the first character for some reason would always either M, N, Y, Z so didn't fit my purposes but would have been the chosen answer, by the way does anyone know why it would always yield those particular letters?

Here is the preview of my modified version

echo rtrim(base64_encode(md5(microtime())),"=");

runner up

Jason Aller
3,66028 gold badges43 silver badges40 bronze badges
asked Sep 26, 2013 at 1:07
5
  • 17
    Why does it need to be achieved within one line of code? Commented Sep 26, 2013 at 1:12
  • If you guys are wondering why the first letter, well I am doing some testing with div elements... classes or ids do not accept numbers on the first character and they dont accept special character anywhere Commented Sep 26, 2013 at 1:36
  • Prefix those with an underscore _0000 works. Commented Sep 26, 2013 at 1:52
  • "_0000".sha1(time()); - prefix via simple string concatenation Commented Sep 26, 2013 at 2:06
  • From 2010: PHP random string generator Commented Dec 5, 2023 at 1:52

18 Answers 18

30

Rather than shuffling the alphabet string , it is quicker to get a single random char .

Get a single random char from the string and then append the md5( time( ) ) to it . Before appending md5( time( ) ) remove one char from it so as to keep the resulting string length to 32 chars :

substr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", mt_rand(0, 51), 1).substr(md5(time()), 1);

Lowercase version :

substr("abcdefghijklmnopqrstuvwxyz", mt_rand(0, 25), 1).substr(md5(time()), 1);

Or even shorter and a tiny bit faster lowercase version :

chr(mt_rand(97, 122)).substr(md5(time()), 1);
/* or */
chr(mt_rand(ord('a'), ord('z'))).substr(md5(time()), 1);


A note to anyone trying to generate many random strings within a second:
Since
time( ) returns time in seconds , md5( time( ) ) will be same throughout a given second-of-time due to which if many random strings were generated within a second-of-time, those probably could end up having some duplicates .


I have tested using below code . This tests lower case version :

 $num_of_tests = 100000;
 $correct = $incorrect = 0;
 for( $i = 0; $i < $num_of_tests; $i++ )
 {
 $rand_str = substr( "abcdefghijklmnopqrstuvwxyz" ,mt_rand( 0 ,25 ) ,1 ) .substr( md5( time( ) ) ,1 );
 $first_char_of_rand_str = substr( $rand_str ,0 ,1 );
 if( ord( $first_char_of_rand_str ) < ord( 'a' ) or ord( $first_char_of_rand_str ) > ord( 'z' ) )
 {
 $incorrect++;
 echo $rand_str ,'<br>';
 }
 else
 {
 $correct++;
 }
 }
 echo 'Correct: ' ,$correct ,' . Incorrect: ' ,$incorrect ,' . Total: ' ,( $correct + $incorrect );
BugHunterUK
9,05618 gold badges75 silver badges132 bronze badges
answered Sep 26, 2013 at 2:20
Sign up to request clarification or add additional context in comments.

7 Comments

Is there a probability that the first is ever a number? i executed the it about 50 times and got a number as first character but happened once 30128fb9b80c5697a4a3954b96e1295
I cannot see any reason except if the values in the mt_rand are not correct . I think it should be mt_rand(0, 50) . It was mt_rand(0, 51) previously .
Perhaps you are right, the first char is 0, I will now only use lower case chars, since the alphabet has 26 letters then the max param should be 25
With my corrected solution I have generated 100,000 strings and none of those started with numeric character . I have tested the lowercase solution for 100,000 strings and the solution seemed perfect .
Awesome, what did you use to generate the strings, also, just wondering how to benchmark my self the performance of these codes? any advice would be awesome
|
30

I had found something like this:

$length = 10;
$randomString = substr(str_shuffle(md5(time())),0,$length);
echo $randomString;
answered Oct 25, 2013 at 13:18

1 Comment

This is better version than the one above, as it is aways unique and has char lenght in it.
7

I decided this question needs a better answer. Like code golf! This also uses a better random byte generator.

preg_replace("/[\/=+]/", "", base64_encode(openssl_random_pseudo_bytes(8)));

Increase the number of bytes for a longer password, obviously.

answered Sep 4, 2014 at 8:54

1 Comment

You could use str_replace(array('/', '=', '+'), '', ..., that might be faster.
6

If you need it to start with a letter, you could do this. It's messy... but it's one line.

$randomString = substr(str_shuffle("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 1) . substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 10);
echo $randomString;
answered Sep 26, 2013 at 1:10

11 Comments

He never said it needed to be alfanumeric.
@Alix Axel: what do you actually mean?
You don't need the second str_shuffle.
actually it can be alphanumeric, however the first character needs to be an alphabet letter]
@Alix Axel: there won't be numbers then in the left part of string. OP expects it to be alpha-numeric except of the first character. That's obvious from base64 part of the question.
|
4

Creates a 200 char long hexdec string:

$string = bin2hex(openssl_random_pseudo_bytes(100));

maaarghk's answer is better though.

answered Sep 4, 2014 at 18:26

Comments

3

base_convert(microtime(true), 10, 36);

answered May 25, 2014 at 5:08

1 Comment

Please share more details. Which parts of that snippet provide randomness?
3

You can try this:

 function KeyGenerator($uid) {
 $tmp = '';
 for($z=0;$z<5;$z++) {
 $tmp .= chr(rand(97,122)) . rand(0,100);
 }
 $tmp .= $uid;
 return $tmp;
 }
answered Dec 26, 2015 at 1:10

Comments

2

I have generated this code for you. Simple, short and (resonably) elegant.

This uses the base64 as you mentioned, if length is not important to you - However it removes the "==" using str_replace.

<?php
 echo str_ireplace("==", "", base64_encode(time()));
?>
answered Sep 26, 2013 at 1:14

4 Comments

Meh, use rtrim() instead!
I agree use rtrim(), also the last I checked == did not have uppercase and lowercase versions. So why use case-insensitive replacement?
I never knew about rtrim() - I will take this into account for the future, thanks! As for case insensitive, thats habit.
Please share more details. Which parts of that snippet provide randomness?
2

I use this function

usage:

 echo randomString(20, TRUE, TRUE, FALSE);
 /**
 * Generate Random String
 * @param Int Length of string(50)
 * @param Bool Upper Case(True,False)
 * @param Bool Numbers(True,False)
 * @param Bool Special Chars(True,False)
 * @return String Random String
 */
 function randomString($length, $uc, $n, $sc) {
 $rstr='';
 $source = 'abcdefghijklmnopqrstuvwxyz';
 if ($uc)
 $source .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
 if ($n)
 $source .= '1234567890';
 if ($sc)
 $source .= '|@#~$%()=^*+[]{}-_';
 if ($length > 0) {
 $rstr = "";
 $length1= $length-1;
 $input=array('a','b','c','d','e','f','g','h','i','j,''k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z') 
 $rand = array_rand($input, 1)
 $source = str_split($source, 1);
 for ($i = 1; $i <= $length1; $i++) {
 $num = mt_rand(1, count($source));
 $rstr1 .= $source[$num - 1];
 $rstr = "{$rand}{$rstr1}";
 }
 }
 return $rstr;
 }
answered Sep 26, 2013 at 1:14

23 Comments

$uc == 1, $n == 1 :-S
@zerkms 1 is true, 0 is false
echo improve(constant(Alix),True); --- it throws a MayBeAnotherDay exception :-(
@JoseDavidGarciaLlanos: OP = Original Poster = YOU. =)
@EmilioGort: I never said it needed to be. You can just drop it.
|
1

I'm using this one to generate dozens of unique strings in a single go, without repeating them, based on other good examples above:

$string = chr(mt_rand(97, 122))
 . substr(md5(str_shuffle(time() . rand(0, 999999))), 1);

This way, I was able to generate 1.000.000 unique strings in ~5 seconds. It's not THAT fast, I know, but as I just need a handful of them, I'm ok with it. By the way, generating 10 strings took less than 0.0001 ms.

answered Nov 28, 2014 at 15:35

Comments

1

JavaScript Solution:

function randomString(pIntLenght) { 
 var strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
 var strRandomstring = ";
 for (var intCounterForLoop=0; intCounterForLoop < pIntLenght; intCounterForLoop++) {
 var rnum = Math.floor(Math.random() * strChars.length);
 strRandomstring += strChars.substring(rnum,rnum+1);
 }
 return strRandomstring;
}
alert(randomString(20));

Reference URL : Generate random string using JavaScript

PHP Solution:

function getRandomString($pIntLength = 30) {
 $strAlphaNumericString = ’0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;
 $strReturnString = ";
 for ($intCounter = 0; $intCounter < $pIntLength; $intCounter++) {
 $strReturnString .= $strAlphaNumericString[rand(0, strlen($strAlphaNumericString) - 1)];
 }
 return $strReturnString;
}
echo getRandomString(20);

Reference URL : Generate random String using PHP

answered Dec 24, 2014 at 6:34

Comments

1

This function returns random lowercase string:

function randomstring($len=10){
 $randstr='';
 for($iii=1; $iii<=$len; $iii++){$randstr.=chr(rand(97,122));};
 return($randstr);
};
answered Aug 18, 2015 at 5:28

Comments

1

I find that base64 encoding is useful for creating random strings, and use this line:

base64_encode(openssl_random_pseudo_bytes(9));

It gives me a random string of 12 positions, with the additional benefit that the randomness is "cryptographically strong".

answered Dec 29, 2015 at 10:30

Comments

1

to generate strings consists of random characters, you can use this function

public function generate_random_name_for_file($length=50){
 $key = '';
 $keys = array_merge(range(0, 9), range('a', 'z'));
 for ($i = 0; $i < $length; $i++) {
 $key .= $keys[array_rand($keys)];
 }
 return $key;
}
answered Feb 13, 2016 at 12:18

Comments

1

It really depends on your requirements.

I needed strings to be unique between test runs, but not many other restrictions.

I also needed my string to start with a character, and this was good enough for my purpose.

$mystring = "/a" . microtime(true);

Example output:

a1511953584.0997

answered Nov 29, 2017 at 11:17

4 Comments

microtime does not use any random parts, and starting with a fixed letter doesn't provide any more randomness
@NicoHaase I didn't claim either of those two things, so not sure why you comment on this (and downvote?)
What do you mean by "I didn't claim either of those two things"? That's what the whole question is about: generating a random string
The question starts with to generate random/unique strings and in my case, just as for the OP (probably), being unique between function calls is good enough, it doesn't need to be truly random. They also write I need the string to begin with a letter without specifying randomness requirements for the letter itself. Since I had a use case of my own with similar requirements, which worked, I posted that.
1

How to match the OPs original request in an awful way (expanded for readability):

// [0-9] ASCII DEC 48-57
// [A-Z] ASCII DEC 65-90
// [a-z] ASCII DEC 97-122
// Generate: [A-Za-z][0-9A-Za-z]
$r = implode("", array_merge(array_map(function($a)
 {
 $a = [rand(65, 90), rand(97, 122)];
 return chr($a[array_rand($a)]);
 }, array_fill(0, 1, '.')),
 array_map(function($a)
 {
 $a = [rand(48, 57), rand(65, 90), rand(97, 122)];
 return chr($a[array_rand($a)]);
 }, array_fill(0, 7, '.'))));

One the last array_fill() would would change the '7' to your length - 1.

For one that does all alpha-nurmeric (And still slow):

// [0-9A-Za-z]
$x = implode("", array_map(function($a)
 {
 $a = [rand(48, 57), rand(65, 90), rand(97, 122)];
 return chr($a[array_rand($a)]);
 }, array_fill(0, 8, '.')));
answered Jun 10, 2018 at 6:21

Comments

1

The following one-liner meets the requirements in your question: notably, it begins with a letter.

substr("abcdefghijklmnop",random_int(0, 16),1) . bin2hex(random_bytes(15))

If you didn't care whether the string begins with a letter, you could just use:

bin2hex(random_bytes(16))

Note that here we use random_bytes and random_int, which were introduced in PHP 7 and use cryptographic random generators, something that is important if you want unique strings to be hard to guess. Many other solutions, including those involving time(), microtime(), uniqid(), rand(), mt_rand(), str_shuffle(), array_rand(), and shuffle(), are much more predictable and are unsuitable if the random string will serve as a password, a bearer credential, a nonce, a session identifier, a "verification code" or "confirmation code", or another secret value.

I also list other things to keep in mind when generating unique identifiers, especially random ones.

answered Jul 27, 2020 at 16:38

Comments

1

True one liner random string options:

implode('', array_rand(array_flip(str_split(str_shuffle('abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ'))), 21));
md5(microtime() . implode('', array_rand(array_flip(str_split(str_shuffle('abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ'))), 21)));
sha1(microtime() . implode('', array_rand(array_flip(str_split(str_shuffle('abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ'))), 21)));
answered Dec 6, 2022 at 1:27

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.