PHP Fast Random String Function

I need a quick way to generate a-Z0-9 random strings in PHP. I was doing some thinking and testing, this is what I still have:

function randStr($length) { $result = null; $replace = array('/', '+', '='); while(!isset($result[$length-1])) { $result.= str_replace($replace, NULL, base64_encode(mcrypt_create_iv($length, MCRYPT_RAND))); } return substr($result, 0, $length); } 

The function is fast compared to functions that iterate over and select a random ASCII value for each char, but I'm interested in the "quality" of my implementation. I don’t know much about cryptography, so I would like to ask if such a function creates “good” random values ​​or not.

  • mcrypt_create_iv seems to return some random binary values ​​actually used to encrypt / decrypt data using the mcrypt library. What is the effect of base64_encode on this kind of binary data, do I really reduce entropy when I am base64_encode?

  • How does the second parameter for mcrypt_create_iv affect my results? The MCRYPT_RAND manual states that MCRYPT_RAND is a "system random number generator". Is it OS specific and, if so, how are good values ​​created?

+6
performance string php random cryptography
source share
4 answers
  • base64_encoding will not reduce entropy, it's just a different representation of the same data.

  • It depends on the OS, but I think the generated random values ​​are good enough with this function. In PHP 5.3, you must pre-seed the generator, this can be a problem if you use this code on different servers.

+3
source share

This should be safe for most systems and fast:

 bin2hex(openssl_random_pseudo_bytes($length / 2)); 

(1,000,000 entries, line length 100 characters)

 rstr1: 198.93383002281 rstr2: 35.5827729702 rstr3: 6.8811790943146 rstr4: 5.4545040130615 this:: 3.9310231208801 
+5
source share

From my tests, your function is already very fast, but I managed to move to a faster one, even if it reduces entropy

 fcn time rstr1: 1.074s (slowest) rstr2: 0.917s rstr3: 0.028s (yours) rstr4: 0.022s (mine) 

In my script, I needed 1k lines as fast as possible.

 function rstr1($length) { // @see http://stackoverflow.com/a/853846/11301 $alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; return substr(str_shuffle(str_repeat($alphabet, $length)), 0, $length); } function rstr2($length) { // @see http://stackoverflow.com/a/853870/11301 $alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; $str = ''; $count = strlen($alphabet); while ($length--) { $str .= $alphabet[mt_rand(0, $count-1)]; } return $str; } function rstr3($length) { // @see http://stackoverflow.com/q/4757392/11301 $result = null; $replace = array('/', '+', '='); while(!isset($result[$length-1])) { $result.= str_replace($replace, NULL, base64_encode(mcrypt_create_iv($length, MCRYPT_RAND))); } return substr($result, 0, $length); } function rstr4($length) { // uses md5 & mt_rand. Not as "random" as it could be, but it works, and its fastest from my tests return str_shuffle(substr(str_repeat(md5(mt_rand()), 2+$length/32), 0, $length)); } // test the functions for($i=0; $i<1000; $i++){ #$x = rstr1(1024); # #$x = rstr2(1024); # 0.917s #$x = rstr3(1024); # 0.028s #$x = rstr4(1024); # 0.022s #dlog($x); return; } 
+2
source share

This is how I do it, although it is not entirely cryptographic; Mersenne Twister is fast and reliable, but not the safest.

 function str_rand($chars, $len) { $str = ''; for ($max = strlen($chars) - 1, $i = 0; $i < $len; ++$i) { $str .= $chars[mt_rand(0, $max)]; } return $str; } $strRand = str_rand('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 40); 
-one
source share

All Articles