What is mt_rand function in php?

(PHP 4, PHP 5, PHP 7, PHP 8)

mt_randGenerate a random value via the Mersenne Twister Random Number Generator

Description

mt_rand(): int

mt_rand(int $min, int $max): int

Many random number generators of older libcs have dubious or unknown characteristics and are slow. The mt_rand() function is a drop-in replacement for the older rand(). It uses a random number generator with known characteristics using the » Mersenne Twister, which will produce random numbers four times faster than what the average libc rand() provides.

If called without the optional min, max arguments mt_rand() returns a pseudo-random value between 0 and mt_getrandmax(). If you want a random number between 5 and 15 (inclusive), for example, use mt_rand(5, 15).

Parameters

min

Optional lowest value to be returned (default: 0)

max

Optional highest value to be returned (default: mt_getrandmax())

Return Values

A random integer value between min (or 0) and max (or mt_getrandmax(), inclusive), or false if max is less than min.

Changelog

VersionDescription
7.2.0 mt_rand() has received a bug fix for a modulo bias bug. This means that sequences generated with a specific seed may differ from PHP 7.1 on 64-bit machines.
7.1.0 rand() has been made an alias of mt_rand().
7.1.0 mt_rand() has been updated to use the fixed, correct, version of the Mersenne Twister algorithm. To fall back to the old behaviour, use mt_srand() with MT_RAND_PHP as the second parameter.

Examples

Example #1 mt_rand() example

echo mt_rand() . "\n";
echo 
mt_rand() . "\n";

echo

mt_rand(515);
?>

The above example will output something similar to:

Notes

Warning

min max range must be within the range mt_getrandmax(). i.e. (max - min) <= mt_getrandmax() Otherwise, mt_rand() may return poorer random numbers than it should.

See Also

  • mt_srand() - Seeds the Mersenne Twister Random Number Generator
  • mt_getrandmax() - Show largest possible random value
  • random_int() - Generates cryptographically secure pseudo-random integers
  • random_bytes() - Generates cryptographically secure pseudo-random bytes
  • openssl_random_pseudo_bytes() - Generate a pseudo-random string of bytes
  • rand() - Generate a random integer

cyrax21 at gmail dot com

10 years ago

i wanted to spot out the big difference between rand and mt_rand when producing images using randomness as noise.

for example this is a comparation between rand and mt_rand on a 400x400 pixel png: http://oi43.tinypic.com/vwtppl.jpg

code:
header("Content-type: image/png");
$sizex=800;
$sizey=400; $img = imagecreatetruecolor($sizex,$sizey);
$ink = imagecolorallocate($img,255,255,255);

for(

$i=0;$i<$sizex/2;$i++) {
  for(
$j=0;$j<$sizey;$j++) {
 
imagesetpixel($img, rand(1,$sizex/2), rand(1,$sizey), $ink);
  }
}

for(

$i=$sizex/2;$i<$sizex;$i++) {
  for(
$j=0;$j<$sizey;$j++) {
 
imagesetpixel($img, mt_rand($sizex/2,$sizex), mt_rand(1,$sizey), $ink);
  }
}
imagepng($img);
imagedestroy($img);
?>

the differences reduce when reducing the pixels of the image.. infact for a 100x100 pixel image the noise produced from the rand function is much more realistic than how it is for a 400x400 image: http://oi39.tinypic.com/5k0row.jpg

(rand is on the left, mt_rand on the right)

chagenbu at php dot net

15 years ago

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.

Hayley Watson

9 years ago

Another graphical comparison of rand() and mt_rand(). It effectively draws a graph showing how the last generated number affects the next by plotting the numbers in consecutive pairs against each other.

header("Content-type: image/png");
$sizex=800;
$sizey=800;$img = imagecreatetruecolor(2 * $sizex,$sizey);
$black = imagecolorallocate($img,0, 0, 0);
imagefilledrectangle($img, 0, 0, 2 * $sizex, $sizey, imagecolorallocate($img, 255, 255, 255));$p = 0;
for(
$i=0; $i < 100000; $i++) {
   
$np = rand(0,$sizex);
   
imagesetpixel($img, $p, $np, $black);
   
$p = $np;
}
$p = 0;
for(
$i=0; $i < 100000; $i++) {
   
$np = mt_rand(0,$sizex);
   
imagesetpixel($img, $p + $sizex, $np, $black);
   
$p = $np;
}
imagepng($img);
imagedestroy($img);
?>

falkartis at gmail dot com

8 years ago

I wrote another function to get a random float, if its not precise enougth jut add some '0' to the $mul parameter.

function f_rand($min=0,$max=1,$mul=1000000){
    if (
$min>$max) return false;
    return
mt_rand($min*$mul,$max*$mul)/$mul;
}
?>
I made following  tests:
    echo f_rand()."
"
;              //0.497153
   
echo f_rand(0.5)."
"
;           //0.857822
   
echo f_rand(0.5,0.6)."
"
;       //0.599956
   
echo f_rand(0,10)."
"
;          //5.801949
   
echo f_rand(0,2,2)."
"
;         //1.5
   
echo f_rand(0,2,10)."
"
;        //1.7
?>

contact at sheyd dot fr

10 years ago

To quickly build a human-readable random string for a captcha per example :

function random($length = 8)
{     
   
$chars = 'bcdfghjklmnprstvwxzaeiou';

        for (

$p = 0; $p < $length; $p++)
    {
       
$result .= ($p%2) ? $chars[mt_rand(19, 23)] : $chars[mt_rand(0, 18)];
    }

        return

$result;
}
?>

Note that I have removed q and y from $chars to avoid readability problems.

Miller

9 years ago

Another generic random string function, but very small and fast.

function mt_rand_str ($l, $c = 'abcdefghijklmnopqrstuvwxyz1234567890') {
    for (
$s = '', $cl = strlen($c)-1, $i = 0; $i < $l; $s .= $c[mt_rand(0, $cl)], ++$i);
    return
$s;
}

echo

mt_rand_str(8); // Something like mp2tmpsw
echo mt_rand_str(6, '0123456789ABCDEF'); // Something like B9CD0F
?>

j dot s dot shiuan at gmail dot com

11 years ago

Another good way to get a random float is to divide the result of mt_rand.
Let's say we want a float between 0.75 and 1.25.

$i

= mt_rand(75,125) / 100;?>

zolaar at nothanks dot com

15 years ago

a better (and likely faster) way to generate a random 6-digit hex string:

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

geompse at yopmail dot com

14 years ago

mt_rand() is not faster than rand() !

Tested over 100'000 iterations, with none/various/random arguments, mt_rand is always 3% slower than rand().

rok dot kralj at gmail dot com

15 years ago

mt_rand function returns just a whole numbers. If you want a random float, then here's an elegant way:

function random_float ($min,$max) {
   return (
$min+lcg_value()*(abs($max-$min)));
}
?>

Nikhil S.

2 years ago

A nifty function to generate pretty coupon codes. This will generate unique coupon codes and you don't have to do a database check whether the code already exists.

function giftCodes(){
   
$a='';
    for(
$j=0; $j<=4; $j++){
       
$c = 4;
        if(
$j == 1) { $a .= date("d"); $c=2; }
        if(
$j == 3) { $a .= date("m"); $c=2; }
        if(
$j == 4) { $a .= date("y"); $c=2; }
        for(
$i=0; $i<= $c; $i++)
           
$a .= chr(!mt_rand(0,2)?mt_rand(48,57):mt_rand(65,90));
       
$a .='-';
    }
    return
substr($a, 0, -1);
}
?>

fabiovh on gmail

14 years ago

performance: for a repetitive task, it's much faster not to use the limit parameters, as shown below. just use the % operator.

$t=microtime(true);
for($i=0;$i<1000000;$i++)
mt_rand()%3;
echo microtime(true)-$t;

echo '|';

$t=microtime(true);
for($i=0;$i<1000000;$i++)
mt_rand(0,2);
echo microtime(true)-$t;

echo '|';

$t=microtime(true);
for($i=0;$i<1000000;$i++)
mt_rand();
echo microtime(true)-$t;

output: 0.316797971725|0.442242145538|0.253082036972

demogracia at metropoliglobal dot com

20 years ago

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

mark omohundro, ajamyajax dot com

13 years ago

just another example: both of these routines return a random decimal number between -1 and 1... since rand() only returns a max 'integer' value while mt_rand() return a max 'long' value -- at least on some platforms -- mt_rand() could be the better precision choice for some on any variation to this routine (but i don't think it matters here):

echo "-1 to 1 rand() value: ". (rand(getrandmax()*-1,getrandmax())/getrandmax()). "\n
"
;
echo
"-1 to 1 mt_rand() value: ". (mt_rand(mt_getrandmax()*-1,mt_getrandmax())/mt_getrandmax()). "\n";
?>

nowhere at where dot net

17 years ago

Allows characters 0-9, a-z
Weighted (and tested) ok.

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

nospamremove dot francois dot gannaz at silecs dot info

6 years ago

rand() comes from the libc, and mt_rand() is internal to PHP. So the differences vary with their respective versions.

On a 64b Debian Stretch with PHP 5.6.21, there is no visible difference: http://oi64.tinypic.com/2nkqas6.jpg

This image compares the two functions. In the top half with random points, in the lower half with random intensity on each point. This is totally different from what was obtained 4 years ago in another note, with an unknown environment.

Here is the code for this visual comparison.
$sizex = 400;
$sizey = 400;$img = imagecreatetruecolor(2 * $sizex, 2 * $sizey);
$white = imagecolorallocate($img, 255, 255, 255);
$inks = array_map(
    function(
$r) use($img) { return imagecolorallocate($img, $r, $r, $r); },
   
range(0, 255)
);
for (
$x = 0 ; $x < $sizex ; $x++) {
    for (
$y = 0 ; $y < $sizey ; $y++) {
       
// placing ($sizex x $sizey) white points at random in the top half
       
imagesetpixel($img, rand(0, $sizex - 1), rand(0, $sizey - 1), $white);
       
imagesetpixel($img, $sizex + mt_rand(0, $sizex - 1), mt_rand(0, $sizey - 1), $white);
       
// random intensity for each point in the lower half
       
imagesetpixel($img, $x, $sizey + $y, $inks[rand(0, 255)]);
       
imagesetpixel($img, $sizex + $x, $sizey + $y, $inks[mt_rand(0, 255)]);
    }
}
header("Content-type: image/png");
imagepng($img);
?>

Jeff Cours

7 years ago

With PHP 5.3.3, we're seeing odd behavior on 32 bit Linux.

This works fine on 64 bit Linux:
printf ("%08x\n", mt_rand (0, 0xFFFFFFFF));
?>
but on our 32 bit Linux development server, it's always yielding "00000000".

On that same machine, this:
printf ("%08x\n", mt_rand (0, 0xFFFFFFF0));
?>
seems to always yield either 00000000 or a number in the range fffffff2 to ffffffff. This:
printf ("%08x\n", mt_rand (0, 0xFFFFFF00));
?>
gives numbers where the last two digits vary, and so on through at least 0xF0000000.

However, this:
printf ("%08x\n", mt_rand (0, 0x7FFFFFFF));
?>
seems to be well-behaved.

The moral? On 32 bit systems, be careful about crossing the signed number boundary, 0x7FFFFFFF.

nilesh at itech7 dot com

12 years ago

A class to generate 99.5% unqiue strings. I found that there is only one or two characters common between two subsequent strings.

class Local_RandomString {

    protected

$_length;
  protected
$_prevRand;

  public function

__construct($length = 15) { $this->_length = $length;

  }

  public function

getRand() { $randStr = null;   
   
$args[] = 'N' . $this->_length;

    for(

$i = 0; $i < $this->_length; $i++) {
     
$args[] = mt_rand();     
    }
$randStr = substr(base64_encode((call_user_func_array('pack', $args))), 1, $this->_length);
   
$this->_prevRand = $randStr;
    return
$randStr;

  }

  public function

setLength($l) { $this->_length = (int) $l;

        if(

$this->_length <= 0) {
      throw new
Exception('Invalid random string length');
    }

  }

  public function

getPrevRand() {

        return

$this->_prevRand;

  }

}

?>

Mark Seecof

14 years ago

If you need some pseudorandom bits for security or cryptographic purposes (e.g.g., random IV for block cipher, random salt for password hash) mt_rand() is a poor source.  On most Unix/Linux and/or MS-Windows platforms you can get a better grade of pseudorandom bits from the OS or system library, like this:

// get 128 pseudorandom bits in a string of 16 bytes$pr_bits = '';// Unix/Linux platform?
$fp = @fopen('/dev/urandom','rb');
if (
$fp !== FALSE) {
   
$pr_bits .= @fread($fp,16);
    @
fclose($fp);
}
// MS-Windows platform?
if (@class_exists('COM')) {
   
// http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx
   
try {
       
$CAPI_Util = new COM('CAPICOM.Utilities.1');
       
$pr_bits .= $CAPI_Util->GetRandom(16,0);// if we ask for binary data PHP munges it, so we
        // request base64 return value.  We squeeze out the
        // redundancy and useless ==CRLF by hashing...
       
if ($pr_bits) { $pr_bits = md5($pr_bits,TRUE); }
    } catch (
Exception $ex) {
       
// echo 'Exception: ' . $ex->getMessage();
   
}
}

if (

strlen($pr_bits) < 16) {
   
// do something to warn system owner that
    // pseudorandom generator is missing
}
?>

NB: it is generally safe to leave both the attempt to read /dev/urandom and the attempt to access CAPICOM in your code, though each will fail silently on the other's platform.  Leave them both there so your code will be more portable.

Anonymous

18 years ago

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.

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

Robin Leffmann

11 years ago

Fast, pseudo-random binary data generation using mt_rand():

function rnd_bin( $length )
{
    while( @
$c++ * 16 < $length )
        @
$tmp .= md5( mt_rand(), true );
    return
substr( $tmp, 0, $length );
}
?>

What is the difference between Rand and Mt_rand?

The mt_rand() function is a drop-in replacement for the older rand(). It uses a random number generator with known characteristics using the » Mersenne Twister, which will produce random numbers four times faster than what the average libc rand() provides.

How to auto generate number in PHP?

The rand() function generates a random integer. Example tip: If you want a random integer between 10 and 100 (inclusive), use rand (10,100). Tip: As of PHP 7.1, the rand() function has been an alias of the mt_rand() function.

How to generate multiple random numbers in PHP?

To generate a random number between two end points, pass mt_rand( ) two arguments: $random_number = mt_rand(1, 100); Calling mt_rand( ) without any arguments returns a number between 0 and the maximum random number, which is returned by mt_getrandmax( ) .

Is Mt_rand secure?

From http://php.net/manual/en/function.mt-rand.php: Caution This function does not generate cryptographically secure values, and should not be used for cryptographic purposes.