Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Mathematical Functions : mt_rand

mt_rand

Generate a better random value (PHP 4, PHP 5)
int mt_rand ( [int min, int max] )

Example 1152. mt_rand() example

<?php
echo mt_rand() . "\n";
echo
mt_rand() . "\n";

echo
mt_rand(5, 15);
?>

The above example will output something similar to:

1604716014
1478613278
6

Related Examples ( Source code ) » mt_rand



Code Examples / Notes » mt_rand

bradpeabody

[Editorial note: This suggested "security" improvement simply punts the issue to the operating system: there is no guarantee that the operating system will work any better than the Mersenne twister (although it may have more entropy available)]
If you want some random text that is more secure than what can get from a built in PHP method, you can simply do:
<?php
$myRandomText = shell_exec('head -c 128 < /dev/urandom');
?>
That will get around the fact that rand() and mt_rand() are a bad place to start generating something that is supposed to be cryptographically secure.
The only down sides to this that I see are:
a) Ugly
b) Slow (have to launch external processes)
c) Not portable (can't do this on Windows)
But if you can live with that, this will be much more secure than using rand() or mt_rand().
- Brad


sean

You really shouldn't generate a number to determine the _type_ of the char, then the char itself.  If security is an issue for you, and you want to maintain as much entropy as possible, you should use a function similar to the one below.  Since this seems to be getting repeated over-and-over, I explained (beat into the ground?) the issue on http://www.codeaholics.com/randomCode.php
The code:
<?php
////
// Returns a random code of the specified length, containing characters that are
// equally likely to be any of the digits, uppercase letters, or  lowercase letters.
//
// The default length of 10 provides 839299365868340224 (62^10) possible codes.
//
// NOTE: Do not call wt_srand().  It is handled automatically in PHP 4.2.0 and above
//       and any additional calls are likely to DECREASE the randomness.
////
function randomCode($length=10){
$retVal = "";
while(strlen($retVal) < $length){
$nextChar = mt_rand(0, 61); // 10 digits + 26 uppercase + 26 lowercase = 62 chars
if(($nextChar >=10) && ($nextChar < 36)){ // uppercase letters
$nextChar -= 10; // bases the number at 0 instead of 10
$nextChar = chr($nextChar + 65); // ord('A') == 65
} else if($nextChar >= 36){ // lowercase letters
$nextChar -= 36; // bases the number at 0 instead of 36
$nextChar = chr($nextChar + 97); // ord('a') == 97
} else { // 0-9
$nextChar = chr($nextChar + 48); // ord('0') == 48
}
$retVal .= $nextChar;
}
return $retVal;
}
?>


ripat

Yet another snippet to generate a password.
<?php
 $acceptedChars = 'azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN0123456789';
 $max = strlen($acceptedChars)-1;
 $password = null;
 for($i=0; $i < 8; $i++) {
   $password .= $acceptedChars{mt_rand(0, $max)};
 }
 echo $password;
?>
I have tried several ways of doing it but this simple one seems to be the fastest.


tmx

When using this function, it doesn't matter which order the numbers go in.
     mt_rand(16,5)
works just as well as
     mt_rand(5,16)
Which can be useful if you are pulling values from a database, that could be negative or positive.
     mtrand(0,$anyinteger)
Hope this helps someone


daeken_9999

This is a fixed version of the gaussrand() function defined in a note above.
<?php
function gaussrand()
{
static $V2, $V1, $S;
static $phase = 0;
if (phase == 0)
{
while ($S >= 1 || $S == 0)
{
$V1 = 2 * (rand() / getrandmax()) - 1;
$V2 = 2 * (rand() / getrandmax()) - 1;
$S = $V1 * $V1 + $V2 * $V2;
}
$X = $V1 * sqrt(-2 * log($S) / $S);
}
else
$X = $V2 * sqrt(-2 * log($S) / $S);
$phase = 1 - $phase;
return $X;
}
?>


www.mrnaz.com

This function uses mt_rand() to create a random string of specified length from an optionally supplied string of characters. It is good for generating passwords that only consist of alphanumeric characters or codes that must consist of a defined character space such as for barcodes. It can also be used to generate random hexadecimal numbers for things like encryption keys.
It is very fast, and allows for generation of strings of unlimited length.
<?php
function rand_string($len, $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
{
   $string = '';
   for ($i = 0; $i < $len; $i++)
   {
       $pos = rand(0, strlen($chars)-1);
       $string .= $chars{$pos};
   }
   return $string;
}
?>


jsheets

The following function will create a random base64 encoded key, this is very useful for password reset schemes or anything where you want a random string.  To compare the string either compare the base64 encoded value or base64_decode it and compare that.
I do not use md5 because md5 results in only 1-9 and a-f in the string or 32^16 possibilities, by using the extended ASCII table and shuffling the array I am able to get a minimum of 32^127 possibilities with a 32 character string, using a longer string will make your value harder to guess still. A lot of machiens will have 32^255 possibilities in a decoded string.
<?php
function MakeResetKey($min_length = 32, $max_length = 64)
{
  $key = '';
  // build range and shuffle range using ASCII table
  for ($i=0; $i<=255; $i++) {
     $range[] = chr($i);
  }
  // shuffle our range 3 times
  for ($i=0; $i<=3; $i++) {
     shuffle($range);
  }
     // loop for random number generation
  for ($i = 0; $i < mt_rand($min_length, $max_length); $i++) {
     $key .= $range[mt_rand(0, count($range))];
  }
  $return = base64_encode($key);
  if (!empty($return)) {
     return $return;
  } else {
     return 0;
  }
}
?>


james

The Developers Resources article mentioned above should be removed as that site has be down for years. The same article by Gregory Boshoff is available at http://www.phpfive.net/article2.htm

timr

The correct address of the inventor's FAQ is (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/efaq.html). They state that Mersenne Twister may be used for cryptography if you do some post-processing:
"Mersenne Twister is not cryptographically secure. (MT is based on a linear recursion. Any pseudorandom number sequence generated by a linear recursion is insecure, since from sufficiently long subsequence of the outputs, one can predict the rest of the outputs.)
To make it secure, you need to use some Secure Hashing Algorithm with MT. For example, you may gather every eight words of outputs, and compress them into one word (thus the length of the output sequence is 1/8 of the original one)."


chagenbu

The algorithm used by mt_rand() changed in PHP 5.2.1. If you are relying on getting the same sequence from mt_rand() after calling mt_srand() with a known seed, upgrading to PHP 5.2.1 will break your code. See http://bugs.php.net/bug.php?id=40724 for something of an explanation; there is no workaround.

heavyraptor

since my mt_rand_n() function isn't too fast I created a faster and easier function:
<?php
function mt_rand_exclusive($min,$max,$ex) {
 while (true) {
   if (!in_array($rand = mt_rand($min,$max),(array)$ex))
     return $rand;
 }
}
?>
Have fun


magicaltux

Since many people wrote little scripts to generate random sequences, I'll also give mine (which is slightly faster since it makes use of strlen only once, and uses strings instead of arrays) :
<?php
function code($nc, $a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') {
   $l=strlen($a)-1; $r='';
   while($nc-->0) $r.=$a{mt_rand(0,$l)};
   return $r;
}
?>


david

Shouldn't it be a greater than (>) sign rather than a not equal (!=) sign? Because you're just checking to see if it is exactly six. So if it is 7 it, won't try to fix it. So wouldn't this be better?
<?
//....
if (strlen($random_hex) < "6") // sometimes it returns an only 5, or less, char Hex-Code,
  hexcode();        // so the function has to be repeat
elseif (strlen($random_hex) > "6") // sometimes it returns 7 or more characters
//...I don't know how to make it do only six, but your code seems to only check to make sure it doesn't do less than 6; nothing to counter doing more than 6.... so here would be some code to reduce the size back to 6 if it went over.
else
  echo $random_hex; // returns the Hex-Code
}
//...
?>


mskala

Running the output of Mersenne Twister through an unkeyed secure hash is NOT a good way to make it secure, because it'll still have a relatively small internal state which, if recovered, would allow reproduction of the keystream.  A better idea would be to encrypt the output with a keyed encryption algorithm - but if you were going to do that, you wouldn't need a psuedorandom number generator at all, because a counter would be just as good.

mina86

Re: solenoid at hotmail dot united dot kingdom
In theory method shown by selenoid can lead to infinite loop. The correct method would be:
<?php
$randomNumbers = array();
for ($i = 0; i<30; ++$i) $randomNumbers[] = $i;
shuffle($randomNumbers);
for ($i = 20; $i<30; ++$i) unset($randomNumbers[$i]);
$randomNumbers = array_values($randomNumbers);
?>
The last two lines may be in some cases removed.


phil underscore ozil

Quit bothering yourselves.
All it takes to create a secure random-generated password is those three lines:
<?php
$pass = "";
// Generate a 8 char password
for ($i=0; $i<8; $i++)
 $pass .= chr(mt_rand(35, 126));
?>
Note:
In this example, the character's ASCII values range from 35 to 126.
For character's ASCII codes please check:
http://www.keller.com/html-quickref/latin1.html


frans-jan

My try at generating a reasonably secure password:
<?php
function keygen() {
 $tempstring =
 "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO
 PQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABC
 DEFGHIJKLMNOPQRSTUVWXYZ!?@#$%&*[]{}();:,<>~+=-_
 /|\\";
 for($length = 0; $length < mt_rand(10, 15); $length++) {
  $temp = str_shuffle($tempstring);
  $char = mt_rand(0, strlen($temp));
  $pass .= $temp[$char];
 }
 return $pass;
}
echo(keygen());
echo("\n");
?>
This generates a password of an undefined length (in this case, 10 to 15 chars) consisting of numbers, UPPERCASE letters lowercase letters and a set of signs. I have doubled the chance of number and letters to reduce the confusion with my users.


rok dot kralj

mt_rand function returns just a whole numbers. If you want a random float, then here's an elegant way:
<?php
function random_float ($min,$max) {
  return ($min+lcg_value()*(abs($max-$min)));
}
?>


12-mar-2007 08:36

In one of my forums was a discussion about, how to change an image randomly, so i wrote this code using mt_rand ....
I hope you can use it ....
I Forgot something, sorry for that, but here is the correction.
<?php
 //ImageChange.php
 error_reporting(0);//hide the notice for the missing $iRand
 $sPath2ImageDir = Path;//preventing redundancy
 $aImages        = scandir($sBildOrdnerPfad);//Dir 2 Array
 $iImageCount    = count($aImages);//preventing redundancy

 while (getimagesize("{sPath2ImageDir}/{$aImages[$iRand]}")) {//recursion to get an image
  $iRand = mt_rand(2, $iImageCount-1);//min = 2 because $aImages[0] = "." and $aImages[1] = ".."
 }
 
 echo "<img alt=\"Image{$iRand}\" src=\"{sPath2ImageDir}/{$aImages[$iRand]}\" title=\"Image{$iRand}\" />";//show the image
 unset($aImages, $iImageCount, $iRand, $sBildOrdnerPfad);//if this script is used in another script
?>


magicaltux

In answer to David and pHp_n00b, about generating a random 6 characters hexadecimal string...
Well, the easiest solution would be :
<?php
$rand = mt_rand(0x000000, 0xffffff); // generate a random number between 0 and 0xffffff
$rand = dechex($rand & 0xffffff); // make sure we're not over 0xffffff, which shouldn't happen anyway
$rand = str_pad($rand, 6, '0', STR_PAD_LEFT); // add zeroes in front of the generated string
echo $rand;
?>
Some examples of generated stuff :
8514d2
3188ae
028f3e
444397
1de508
071662
You can easily make a function from this code.


heavyraptor

If you need a random number but not the numbers in a specified array, you may use my function below:
<?php
function mt_rand_n($min,$max,$disallowed) {
 // $a must be an array
 if (!is_array($disallowed))
   return false;
 // Create an array with the numbers from $min to $max
 // without the numbers in $disallowed.
 // - range() to create an array with the numbers from $min to $max
 // - array_diff() to create the allowed numbers
 // - since array_diff() doesn't change the keys, we've to change them with
 //   array_values(), to get an normal order (0,1,2,3 ... )
 $numbers = array_values(array_diff(range($min,$max),$disallowed));
 // size of $numbers must be greater than 0
 if (count($numbers) < 1)
   return false;
 // create random number and return it
 return $numbers[mt_rand(0,count($numbers) - 1)];
}
// Example:
$min = 0;
$max = 10;
$disallowed = array(0,1,2,3,4,9,10); // the numbers 1,2,3,6,7, and 8 are disallowed
for ($i = 0; $i < 100; $i++)
 var_dump(mt_rand_n($min,$max,$disallowed));
?>
I hope it helps someone ...
Btw. here's the "un-comment" function:
<?php
function mt_rand_n($min,$max,$disallowed) {
 if (!is_array($disallowed)) return false;
 $numbers = array_values(array_diff(range($min,$max),$disallowed));
 if (count($numbers) < 1) return false;
 return $numbers[mt_rand(0,count($numbers) - 1)];
}
?>
Have fun :)


rollerce

I know a bunch of you have posted little snippets for random number generation, but here's a nifty (in my opinion) little thing I just wrote to create a 10 digit code with hyphens in it. It also negates the use of 0, O, 1, and I, to avoid confusion. I am ALWAYS willing to accept input so if any of you has suggestions to streamline the code, please let me know.
<?php
     function GetID($x){      
        $characters = array("A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "2", "3", "4", "5", "6", "7", "8", "9");
        shuffle($characters);
        for (; strlen($ReqID)<$x;){
          $ReqID .= $characters[mt_rand(0, count($characters))];
         }
        return $ReqID;
       
       }      
     
      $ReqID .= GetID(3);
      $ReqID .= "-";
      $ReqID .= GetID(4);
      $ReqID .= "-";
      $ReqID .= GetID(3);
      echo $ReqID
     
?>


fahri

i did the following, to generate a few random-numbers out of a total amount of numbers, but to create different random-numbers and not double or tripple.
for example i use it to generate 10 random-pics out of 150, and do shurely generate not twice the same...
<?php
$total =  6; // available numbers (of pictures)
$randanzahl = 6; //number of random-number to generate out of $total
function checkifdouble($ran,$i) {
       for($j=1; $j<$i; $j++) {
               if($ran[$j]==$ran[$i]) {
                       $ergebnis="true";
                       break;
               } //endif
               else {
                       $ergebnis="false";
               } //endelse
       } //endfor
return $ergebnis;
}
for ($i=1; $i<=$randanzahl; $i++) {
      $ran[$i] = mt_rand(1, $total);
      if ($i>1) {
              while(checkifdouble($ran,$i)=="true") {
                      $ran[$i] = mt_rand(1, $total);
                      $v=checkifdouble($ran,$i);
                      echo($v);
              } //endif
      }
      echo($ran[$i]."
");
} //enfor
?>
this version is easily for debugging and adaption!
maybe there is a very shorter version...


earlsinclair2001

Here's my shot at writing a secure password generator function:
<?php
function passwordgenerator()
{
$password = "";
$loop = 0;
while ($loop < 12)
{
$randomchar = chr(mt_rand(35, 126));
if (!strstr($password, $randomchar))
{
$password .= $randomchar;
$loop++;
}
}
return $password;
}


amcclung

Here's an elegant way of generating a random float value within a certain range:
$range = $upperBound-$lowerBound;
$num = $lowerBound + $range * mt_rand(0, 32767)/32767;
You should now have a floating point number between your $lowerBound (i.e. 0.5) and $upperBound (0.75) values.


paul nolasco

Here's a more user friendly password generator. You want to make it easier for the user to enter the new password.
Output:
- First character is capitalize
- Rest of the characters are either number or letters (lowercase)
You can change the probability depending on your taste. Also by default it generates a 8-character long password.
<?php
function genPassword($length=8)
{
# first character is capitalize
$pass =  chr(mt_rand(65,90)); // A-Z

# rest are either 0-9 or a-z
for($k=0; $k < $length - 1; $k++)
{
$probab = mt_rand(1,10);

if($probab <= 8)   // a-z probability is 80%
$pass .= chr(mt_rand(97,122));
else // 0-9 probability is 20%
$pass .= chr(mt_rand(48, 57));
}
return $pass;
}
?>


rene

Here is my Function to generate an Array with unique random Numbers between "$from" and "$to".
function random_number_array($count, $from, $to){
  for($i=$from;$i<$to;$i++){
   $number_array[] = $i;
  }
  $random_number_array = array();
  mt_srand ((double) microtime() * 1000000);
  for($i=0;$i<$count;$i++){
     $random_number            = mt_rand(0,count($number_array)-1);
     $key_to_insert_and_delete = array_search($random_number, $number_array);
     $random_number_array[$i]    = $number_array[$key_to_insert_and_delete];
     array_splice($number_array, $key_to_insert_and_delete, 1);
  }
  // Array $random_number_array with $count random Numbers, between $from and $to
  return $random_number_array;
}
I hope its helping you.
Greetings
Rene Andris


11-feb-2004 01:27

Here is a example of a very small, compact, quite random-random string generator. It will make a string with uppercase & lowercase letters, with numbers. You simply need to set $len in the for() structure, and then the string will be in $r.  It has been designed for size, while it's still quite fast.  Mind the wrapping, it should be 1 line.
<?php
for($len=8,$r='';strlen($r)<$len;$r.=chr(!mt_rand(0,2)?
mt_rand(48,57):(!mt_rand(0,1)?mt_rand(65,90):mt_rand
(97,122))));
?>
Armond Carroll


arias

Be carefull with: $characters[mt_rand(0, count($characters))];
"If you want a random number between 5 and 15 (inclusive), for example, use mt_rand (5, 15)."
Array index are between 0 and n-1, but mt_rand generates a number between 0 and n!


mrdlinux

And for those who prefer scaling:
mt_rand() / RAND_MAX * (Max - Min) + Min;


jonathan

An easier password generator than earlsinclair2001.
function easyPassGen($length=10){
$enc = sh1(mt_rand().mt_rand().mt_rand());
$password = sub_str($enc, 1, $length);
return $password;
}
Might help someone (pretty simple though).


nowhere

Allows characters 0-9, a-z
Weighted (and tested) ok.
<?php
function generate_string ($length = 20)
{
   $nps = "";
   for($i=0;$i<$length;$i++)
   {
       $nps .= chr( (mt_rand(1, 36) <= 26) ? mt_rand(97, 122) : mt_rand(48, 57 ));
   }
   return $nps;
}
?>


zolaar

a better (and likely faster) way to generate a random 6-digit hex string:
<?php
$num = mt_rand ( 0, 0xffffff ); // trust the library, love the library...
$output = sprintf ( "%06x" , $num ); // muchas smoochas to you, PHP!
return $output;
?>
The mt_rand function won't give you a number outside the bounds you asked for -- no need to and-off the top bits -- and the sprintf function has params for length-padding & hexidecimal output.  It's likely faster because most of the work is being done by the wicked fast C functions that PHP sits on top of, though YMMV in that dept.


demogracia

<?php
//
// Generates a random string with the specified length
// Chars are chosen from the provided [optional] list
//
function simpleRandString($length=16, $list="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"){
mt_srand((double)microtime()*1000000);
$newstring="";
if($length>0){
while(strlen($newstring)<$length){
$newstring.=$list[mt_rand(0, strlen($list)-1)];
}
}
return $newstring;
}
//
// Generates a random string with the specified length
// Includes: a-z, A-Z y 0-9
//
function randString($length=16) {
  $newstring="";
  if($length>0) {
      while(strlen($newstring)<$length) {
          $randnum = mt_rand(0,61);
          if ($randnum < 10) {
              $newstring.=chr($randnum+48);
          } elseif ($randnum < 36) {
              $newstring.=chr($randnum+55);
          } else {
              $newstring.=chr($randnum+61);
          }
      }
  }
  return $newstring;
}
?>


php_n00b

<?php
// Generates a max."6 char" Hex-Code
function hexcode()
{
$min = hexdec("000000"); // result is 0 and sets the min-value for mt_rand
$max = hexdec("FFFFFF"); // result is 16777215 and sets the max-value for mt_rand
$random = mt_rand($min, $max); // creates a radom number between 0 and 16777215
$random_hex = dechex($random); // transforms the random number into a Hex-Code
// now the test, if the result has 6 chars
if (strlen($random_hex) != "6") // sometimes it returns an only 5, or less, char Hex-Code,
hexcode(); // so the function has to be repeat
else
echo $random_hex; // returns the Hex-Code
}
hexcode();
?>


chris

>Running the output of Mersenne Twister through an unkeyed >secure hash is NOT a good way to make it secure, because it'll >still have a relatively small internal state which, if recovered, >would allow reproduction of the keystream.  A better idea >would be to encrypt the output with a keyed encryption >algorithm - but if you were going to do that, you wouldn't >need a psuedorandom number generator at all, because a >counter would be just as good.
Not true. Mersenne Twister has an ENORMOUS amount of internal state - 4992 bits, bigger than practically any cipher's key length. The point of a secure random number generator is that you cannot predict future outputs based on past OUTPUTS, which is why a hash is applied. Clearly you can predict the future output of any pseudorandom number generator if you can acquire the internal state - a better algorithm will never solve this problem. If you use keyed encryption, recovering the key allows you to predict future outputs.


Change Language


Follow Navioo On Twitter
abs
acos
acosh
asin
asinh
atan2
atan
atanh
base_convert
bindec
ceil
cos
cosh
decbin
dechex
decoct
deg2rad
exp
expm1
floor
fmod
getrandmax
hexdec
hypot
is_finite
is_infinite
is_nan
lcg_value
log10
log1p
log
max
min
mt_getrandmax
mt_rand
mt_srand
octdec
pi
pow
rad2deg
rand
round
sin
sinh
sqrt
srand
tan
tanh
eXTReMe Tracker