PHP 7.0.6 Released

mt_rand

(PHP 4, PHP 5, PHP 7)

mt_randGenerate a better random value

Description

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

Many random number generators of older libcs have dubious or unknown characteristics and are slow. By default, PHP uses the libc random number generator with the rand() function. The mt_rand() function is a drop-in replacement for this. 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).

Caution

This function does not generate cryptographically secure values, and should not be used for cryptographic purposes. If you need a cryptographically secure value, consider using random_int(), random_bytes(), or openssl_random_pseudo_bytes() instead.

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

Version Description
5.3.4 Issues an E_WARNING and returns FALSE if max < min.

Examples

Example #1 mt_rand() example

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

echo 
mt_rand(515);
?>

The above example will output something similar to:

1604716014
1478613278
6

Notes

Warning

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

See Also

User Contributed Notes

cyrax21 at gmail dot com
4 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:
<?php
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)
syouseki
2 months ago
contact at sheyd dot fr
4 years ago
To quickly build a human-readable random string for a captcha per example :

<?php

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.
mark omohundro, ajamyajax dot com
7 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):

<?php
echo "-1 to 1 rand() value: ". (rand(getrandmax()*-1,getrandmax())/getrandmax()). "\n<br/>";
echo
"-1 to 1 mt_rand() value: ". (mt_rand(mt_getrandmax()*-1,mt_getrandmax())/mt_getrandmax()). "\n";
?>
Mark Seecof
7 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:

<?php
// 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.
zolaar at nothanks dot com
9 years ago
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.
Jeff Cours
1 year ago
With PHP 5.3.3, we're seeing odd behavior on 32 bit Linux.

This works fine on 64 bit Linux:
<?php
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:
<?php
printf
("%08x\n", mt_rand (0, 0xFFFFFFF0));
?>
seems to always yield either 00000000 or a number in the range fffffff2 to ffffffff. This:
<?php
printf
("%08x\n", mt_rand (0, 0xFFFFFF00));
?>
gives numbers where the last two digits vary, and so on through at least 0xF0000000.

However, this:
<?php
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.
Miller
2 years ago
Another generic random string function, but very small and fast.

<?php
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
?>
chagenbu at php dot net
9 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.
falkartis at gmail dot com
1 year ago
I wrote another function to get a random float, if its not precise enougth jut add some '0' to the $mul parameter.

<?php

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:
<?php
   
echo f_rand()."<br>";              //0.497153
   
echo f_rand(0.5)."<br>";           //0.857822
   
echo f_rand(0.5,0.6)."<br>";       //0.599956
   
echo f_rand(0,10)."<br>";          //5.801949
   
echo f_rand(0,2,2)."<br>";         //1.5
   
echo f_rand(0,2,10)."<br>";        //1.7
?>
Hayley Watson
3 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.

<?php
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);
?>
geompse at yopmail dot com
8 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().
Robin Leffmann
5 years ago
Fast, pseudo-random binary data generation using mt_rand():

<?php

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

?>
rt
7 years ago
Re: euxneks at NOSPAMgmail dot com

You might also want to add STR_PAD_LEFT and have:

<?php
echo '#' . str_pad( base_convert( mt_rand(0, ( 255*255*255) ), 10, 16 ), 6, '0', STR_PAD_LEFT) . "\n";
?>
Flashbond
1 year ago
A custom unique random generator class example:
<?php
class uniqueRandom {
    private
$rands = array();
    function
generate($min, $max) {
        while (
$rand = mt_rand($min, $max) && array_diff(range($min, $max), $this -> rands)) {
            if (!
in_array($rand, $this -> rands)) {
               
$this-> rands [] = $rand;
                return
$rand;
            }
        }
    }
}
//Test
$myUnique = new uniqueRandom;
for (
$i = 0; $i < 5; $i++) {
    echo
$myUnique -> generate(1, 10)." ";
}
//This will produce 5 unique random numbers from 1 to 10.
?>
Andrew Moore
5 years ago
If you need a predictable set of numbers for a given seed, you may use the following Pure-PHP implementation of a Mersenne Twister

<?php
class Mersenne_Twister
{
  private
$state = array ();
  private
$index = 0;

  public function
__construct($seed = null) {
    if (
$seed === null)
     
$seed = mt_rand();

   
$this->setSeed($seed);
  }

  public function
setSeed($seed) {
   
$this->state[0] = $seed & 0xffffffff;

    for (
$i = 1; $i < 624; $i++) {
     
$this->state[$i] = (((0x6c078965 * ($this->state[$i - 1] ^ ($this->state[$i - 1] >> 30))) + $i)) & 0xffffffff;
    }

   
$this->index = 0;
  }

  private function
generateTwister() {
    for (
$i = 0; $i < 624; $i++) {
     
$y = (($this->state[$i] & 0x1) + ($this->state[$i] & 0x7fffffff)) & 0xffffffff;
     
$this->state[$i] = ($this->state[($i + 397) % 624] ^ ($y >> 1)) & 0xffffffff;

      if ((
$y % 2) == 1) {
       
$this->state[$i] = ($this->state[$i] ^ 0x9908b0df) & 0xffffffff;
      }
    }
  }

  public function
getNext($min = null, $max = null) {
    if ((
$min === null && $max !== null) || ($min !== null && $max === null))
      throw new
Exception('Invalid arguments');

    if (
$this->index === 0) {
     
$this->generateTwister();
    }

   
$y = $this->state[$this->index];
   
$y = ($y ^ ($y >> 11)) & 0xffffffff;
   
$y = ($y ^ (($y << 7) & 0x9d2c5680)) & 0xffffffff;
   
$y = ($y ^ (($y << 15) & 0xefc60000)) & 0xffffffff;
   
$y = ($y ^ ($y >> 18)) & 0xffffffff;

   
$this->index = ($this->index + 1) % 624;

    if (
$min === null && $max === null)
      return
$y;

   
$range = abs($max - $min);

    return
min($min, $max) + ($y % ($range + 1));
  }
}
?>
github.com/elcodedocle
2 years ago
Ever wanted a crypto safe mt_rand()? Not useful for many things I guess (maybe not useful at all), but I recently wanted to build a class able to pick random words from a dictionary in a safe way, so they could be used as passwords. I probably overdid it... The result is my attempt on a "cryptographically secure" mt_rand implementation including a wrapper for selecting and using the best random bytes generator from available extensions and /dev/urandom (about 100 times slower than mt_rand on a single core, by the way, so it's clearly open for improvement if you want to fork it on github.com/elcodedocle/cryptosecureprng, where you can find the docs to it too). Here is the minimized version (note too long):
<?php
/**
* Crypto Secure PRNG
* @copyright  2014 elcodedocle
*/
class CryptoSecurePRNG {
    private
$intByteCount = 4;
    private
$defaultMax = 2147483647;
    private
$mcrypt;
    private
$openssl;
    private
$urandomFileHandler = false;
    public function
getRandomBytesString($byteCount){
       
$chars = '';
        if (
$this->mcrypt) {
           
$chars = mcrypt_create_iv($byteCount, MCRYPT_DEV_URANDOM);
        }
        if (!
$chars && $this->openssl) {
           
$chars = openssl_random_pseudo_bytes($byteCount);
        }
        if (!
$chars && is_resource($this->urandomFileHandler)) {
            while ((
$len  = strlen($chars))< $byteCount) {
               
$chars .= fread($this->urandomFileHandler, $byteCount - $len);
            }
        }
        if (
$len = strlen($chars) < $byteCount) {
            for (
$i=0;$i<$len;$i++) { $chars[$i] = $chars[$i] ^ chr(mt_rand(0, 255)); }
            for (
$i = $len; $i < $byteCount; $i++) {
               
$chars .= chr(mt_rand(0, 255));
            }
        }
        return
$chars;
    }
    public function
rand($min = 0, $max = null){
        if (
$max === null) { $max = $this->defaultMax; }
        if (!
is_int($min)||!is_int($max)) { throw new Exception('$min and $max must be integers'); }
        if (
$min>$max) { throw new Exception('$min must be <= $max'); }
       
$chars = $this->getRandomBytesString($this->intByteCount);
       
$n = 0;
        for (
$i=0;$i<strlen($chars);$i++) {$n|=(ord($chars[$i])<<(8*(strlen($chars)-$i-1)));}
        return (
abs($n)%($max-$min+1))+$min;
    }
    public function
__construct(){
       
$this->mcrypt  = function_exists('mcrypt_create_iv');
       
$this->openssl = function_exists('openssl_random_pseudo_bytes');
        if (
is_readable('/dev/urandom')){ $this->urandomFileHandler = fopen('/dev/urandom', 'r'); }
    }
    public function
__destruct(){
        if (
is_resource($this->urandomFileHandler )) fclose($this->urandomFileHandler);
    }
}

$randGen = new CryptoSecurePRNG();
echo
$randGen->rand();  //outputs rand int between 0 and 2^32
simon at labs dot coop
2 years ago
Something we discovered in Sydney running BBS Systems before the net advent was here, if we didn't seed of another BBS we would going in circles in our System Physicality Abstraction Layers.. The important thing is to seed from a remote system and easy way at the Centroidal Plexus of the web (Chronolabs Cooperative) we offer a seed feed and the following code will randomise you out of the number cycle:

<?php

mt_srand
(file_get_contents('http://seed.feeds.labs.coop'));

?>
hofmann dot johannes at gmail dot com
2 years ago
/dev/urandom provides high entropy, but it is important to remember that it is created by collecting random os garbage from memory - if not enough of that garbage is created reading the file will just block the whole process until there is enough entropy to generate the requested random bytes. in debian-based setups, the rng-tools package can be used to manage entropy.
nilesh at itech7 dot com
5 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.

<?php

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;

  }

}
?>
Anonymous
6 years ago
Just another random password generator. Assembles passwords such as these:

N_v85kA2_s
8k4jz94_H0
30824n6VcN

useful for... whatever. ;)

$underscores holds the maximum allowed number of underscores. Default is two. The function is programmed to not add an underscore at the beginning or end of the password, right after another underscore, or if the maximum # has already been used.

$length holds the length you want the password to be. Default is 10 characters long.

<?php
function alphanumericPass()
{   
   
// Do not modify anything below here
   
$underscores = 2; // Maximum number of underscores allowed in password
   
$length = 10; // Length of password
   
   
$p ="";
    for (
$i=0;$i<$length;$i++)
    {   
       
$c = mt_rand(1,7);
        switch (
$c)
        {
            case (
$c<=2):
               
// Add a number
               
$p .= mt_rand(0,9);   
            break;
            case (
$c<=4):
               
// Add an uppercase letter
               
$p .= chr(mt_rand(65,90));   
            break;
            case (
$c<=6):
               
// Add a lowercase letter
               
$p .= chr(mt_rand(97,122));   
            break;
            case
7:
                
$len = strlen($p);
                if (
$underscores>0&&$len>0&&$len<($length-1)&&$p[$len-1]!="_")
                {
                   
$p .= "_";
                   
$underscores--;   
                }
                else
                {
                   
$i--;
                    continue;
                }
            break;       
        }
    }
    return
$p;
}
?>
nowhere at where dot net
11 years ago
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;
}
?>
David
9 years ago
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
}
//...
?>
euxneks at NOSPAMgmail dot com
7 years ago
Re: keith at ourwebsite dot ca

Here's another way to do it, in one line :)
<?php
echo '#' . str_pad( base_convert( mt_rand(0, ( 255*255*255) ), 10, 16 ), 6, '0' ) . "\n";
?>

str_pad is there in case mt_rand chooses a number that will generate a hex value with less than 6 characters. (you could leave that out but it's not a very clean way to write the hex colors is it :)
William Leslie
8 years ago
Do not rely on the strength of any 'home-brewed' cryptographic algorithm, such as the one posted by dmoree at coker dot edu.  Algorithms such as MD5 and SHA-1 have been the subject of intense academic research and have known security properties.

While it is true that MD5 and SHA-1 are generally no longer recommended for use in new cryptosystems, there are newer algorithms such as SHA-256 that address the older algorithms' weaknesses.  These newer algorithms have not received quite as much scrutiny as their older counterparts, but have still been studied much more carefully than your home-brewed algorithm, most likely.

Dmoree at coker dot edu's concern about rainbow tables is best addressed by a properly applied salting technique.  Every bit of 'salt' added to a cryptographic hash effectively extends the complexity of the password and thus the size of the rainbow table needed to crack it.

Furthermore, wisely chosen password strength policies can mitigate such attacks.
fabiovh on gmail
8 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
bradpeabody at scientology dot net
8 years ago
[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
rok dot kralj at gmail dot com
8 years ago
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)));
}
?>
Rene at mokiba dot de
9 years ago
Here is my Function to generate an Array with unique random Numbers between "$from" and "$to".

<?php
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
Rene at mokiba dot de
9 years ago
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
MagicalTux at ooKoo dot org
9 years ago
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.
Chris
9 years ago
>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.
MagicalTux at ooKoo dot org
9 years ago
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;
}
?>
Anonymous
12 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.

<?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
fahri at konse dot de
10 years ago
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]."<br>");

}
//enfor
?>

this version is easily for debugging and adaption!
maybe there is a very shorter version...
sean at codeaholics dot com
10 years ago
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;
}
?>
mina86 at nospam dot projektcode dot org
10 years ago
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.
Anonymous
9 years ago
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
?>
mskala at ansuz dot sooke dot bc dot ca
11 years ago
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.
jsheets at shadonet dot com
12 years ago
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;
   }
}
?>
demogracia at metropoliglobal dot com
14 years ago
<?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;
}
?>
mrdlinux at yahoo dot com
15 years ago
And for those who prefer scaling:

mt_rand() / RAND_MAX * (Max - Min) + Min;
Pawe Krawczyk
2 years ago
To reiterate the message about *not* using mt_rand() for anything security related, here's a new tool that has been just posted that recovers the seed value given a single mt_rand() output:

http://www.openwall.com/php_mt_seed/README
j dot s dot shiuan at gmail dot com
4 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.

<?php

$i
= mt_rand(75,125) / 100;

?>
wayne
6 years ago
A little useful function to create a random unique number out of an array of unallowed values:

<?php
function rand_except($min, $max, $except)
 
//function returns a random integer between min and max, just like function rand() does.
  // Difference to rand is that the random generated number will not use any of the values
  // placed in $except. ($except must therefore be an array)
  // function returns false if $except holds all values between $min and $max.
 
{
 
//first sort array values
 
sort($except, SORT_NUMERIC);
 
//calculate average gap between except-values
 
$except_count = count($except);
 
$avg_gap = ($max - $min + 1 - $except_count) / ($except_count + 1);
  if (
$avg_gap <= 0)
     return
false;
 
//now add min and max to $except, so all gaps between $except-values can be calculated
 
array_unshift($except, $min - 1);
 
array_push($except, $max + 1);
 
$except_count += 2;
 
//iterate through all values of except. If gap between 2 values is higher than average gap,
  // create random in this gap
 
for ($i = 1; $i < $except_count; $i++)
      if (
$except[$i] - $except[$i - 1] - 1 >= $avg_gap)
         return
mt_rand($except[$i - 1] + 1, $except[$i] - 1);
  return
false;
  }
?>
armencho at gmail dot com
6 years ago
The following function generates a string of arbitrary length (with limitations), composed of random PHP characters (i.e. each an 8-bit value - a byte). Suitable for generating random session strings. Encode as Base64 to transmit over network, where required.

** The function is pretty much one of the fastest (if not THE fastest) methods of generating random strings, as opposed to numerous examples given on this page which go about with char-by-char generation. Sloppy benchmarks estimate a factor of 10 speedup. Keep your websites lean, people. **

The only thing to keep in mind is that, by design, it outputs 8-bit characters, and thus the generated string is not automatically suitable for transmission with various network protocols, unless altered, f.e. URL- or Base64- encoded. Also, again by design, the length of the string is a multiple of 4 characters/bytes. The version below produces a 24 character long string. This will also give you a clean input to get a 32 character long Base64 encoded variant of it.

<?php

function gen_rand_str_24()
{
     return
pack('N6', mt_rand(), mt_rand(), mt_rand(),
         
mt_rand(), mt_rand(), mt_rand());
}

?>

I leave it an exercise to the reader to write a generic (i.e. arbitrary double word length, not 6 dwords as in above) version of it.
rok dot kralj at rok-kralj dot net
4 years ago
This function has limited entrophy. So, if you want to create random string, it will produce only about 2 billion different strings, no matter the length of the string. This can be serous security issue if you are using such strings for session indentifiers, passwords etc.

Many times I have wanted to create *propper* base-64 string (containing only printable characters) of arbitrary length for many purposes. I wrote a function that checks if UNIX random generator is available and uses in that case. If not, it tries to increase the entrophy by accounting in the script execution time.

Here is the function, just try it out!

<?php
function random($len) {
    if (@
is_readable('/dev/urandom')) {
       
$f=fopen('/dev/urandom', 'r');
       
$urandom=fread($f, $len);
       
fclose($f);
    }

   
$return='';
    for (
$i=0;$i<$len;++$i) {
        if (!isset(
$urandom)) {
            if (
$i%2==0) mt_srand(time()%2147 * 1000000 + (double)microtime() * 1000000);
           
$rand=48+mt_rand()%64;
        } else
$rand=48+ord($urandom[$i])%64;

        if (
$rand>57)
           
$rand+=7;
        if (
$rand>90)
           
$rand+=6;

        if (
$rand==123) $rand=45;
        if (
$rand==124) $rand=46;
       
$return.=chr($rand);
    }
    return
$return;
}
?>
Jonathon
8 years ago
Below, andrei suggested a function for generating a list of unique integers, randomly arranged.  In response to a note below that his solution is inefficient, I'm providing an O(N) solution which should be much more efficient, yet still yield a good guarantee of producing randomly ordered integers.

<?php
function SwapShuffle($min, $max) {
 
$last = $max - $min;

  for (
$i=0; $i<=$last; $i++) {
   
$arr[$i] = $min + $i;
  }

  for (
$run=0; $run<7; $run++) {
    for (
$i=0; $i<=$last; $i++) {
     
$target = mt_rand(0, $last);
     
$swap = $arr[$target];
     
$arr[$target] = $arr[$i];
     
$arr[$i] = $swap;
    }
  }

  return
$arr;
}

// Call as:
$result = SwapShuffle(10, 30);
foreach (
$result as $num) {
  echo
"$num\n";
}
?>
www.mrnaz.com
8 years ago
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;
}
?>
frans-jan at van-steenbeek dot net
10 years ago
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.
bimal at sanjaal dot com
1 year ago
I was seeing how much unique and random 5-digits number I can use/generate in one-second's interval of time. (I had another logic for myself to make my number unique based on the date/time stamp value as well).

I found that the mt_rand() numbers are not quite unique. The repetitions  will often occur a lot of times even in the first 50 random numbers generated in a loop.

<?php
header
('Content-Type: text/plain');

$errors = array();
$uniques = array();
for(
$i = 0; $i < 500; ++$i)
{
   
$random_code = mt_rand(10000, 99999);
    if(!
in_array($random_code, $uniques))
    {
       
$uniques[] = $random_code;
    }
    else
    {
       
$errors[] = $random_code;
    }
}

/**
* If you get any data in this array, it is not exactly unique
* Run this script for few times and you may see some repeats
*/
print_r($errors);
?>
To Top