Math 函数
在线手册:中文 英文
PHP手册

mt_rand

(PHP 4, PHP 5)

mt_rand生成更好的随机数

说明

int mt_rand ([ int $min ], int $max )

很多老的 libc 的随机数发生器具有一些不确定和未知的特性而且很慢。PHP 的 rand() 函数默认使用 libc 随机数发生器。mt_rand() 函数是非正式用来替换它的。该函数用了 » Mersenne Twister 中已知的特性作为随机数发生器,它可以产生随机数值的平均速度比 libc 提供的 rand() 快四倍。

如果没有提供可选参数 minmaxmt_rand() 返回 0 到 RAND_MAX 之间的伪随机数。例如想要 5 到 15(包括 5 和 15)之间的随机数,用 mt_rand(5, 15)

Example #1 mt_rand() 范例

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

以上例程的输出类似于:

1604716014
1478613278
6

Note:

在 3.0.7 之前的版本中,max 的含义是 range。要在这些版本中得到和上例相同 5 到 15 的随机数,简短的例子是 mt_rand (5, 11)

参见 mt_srand()mt_getrandmax()rand()

参数

min

Optional lowest value to be returned (default: 0)

max

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

返回值

A random integer value between min (or 0) and max (or mt_getrandmax(), inclusive)

更新日志

版本 说明
4.2.0随机数发生器自动进行播种。

范例

Example #2 mt_rand() example

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

echo 
mt_rand(515);
?>

以上例程的输出类似于:

1604716014
1478613278
6

注释

Caution

The distribution of mt_rand() return values is biased towards even numbers on 64-bit builds of PHP when max is beyond 2^32.

参见


Math 函数
在线手册:中文 英文
PHP手册
PHP手册 - N: 生成更好的随机数

用户评论:

cyrax21 at gmail dot com (01-Mar-2012 04:44)

Taking example from a note above 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)

contact at sheyd dot fr (24-Nov-2011 12:43)

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.

j dot s dot shiuan at gmail dot com (02-Sep-2011 07:12)

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;

?>

rok dot kralj at rok-kralj dot net (30-Aug-2011 05:12)

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

alex at khimic dot remove it dot h dot com (22-Mar-2011 12:16)

This function really generates randow string. One can check it using this:

<?php
header
("Content-type: image/png");
$img = imagecreatetruecolor(500,500);

$ink = imagecolorallocate($img,255,255,255);

for(
$i=0;$i<500;$i++) {
  for(
$j=0;$j<500;$j++) {
 
imagesetpixel($img, mt_rand(1,500), mt_rand(1,500), $ink);
  }
}

imagepng($img);
imagedestroy($img);

?>

This generates 500x500 image with pixel noise.

If you switch mt_rand(1,500) to rand(1,500) you will NOT get pixel noise.

thegreatall at gmail dot com (08-Feb-2011 03:54)

[Editor's note: Minor error in a magic constant and a syntax error fixed. You may also want to consider using uniqid(), depending on your needs.]


This will result in an EXTREMELY fast random string using the following characters: "0123456789abcdefghijklmnopqrstuvwxyz"

you can use:

<?php
base_convert
(mt_rand(0x1D39D3E06400000, 0x41C21CB8E0FFFFFF), 10, 36);
?>

This will be a random number/string always 12 characters. This will only work on 64 bit systems. This will result in a random number/string between: 100000000000 to zzzzzzzzzzzz If you are using a 32 bit system you will need to use:

<?php
base_convert
(mt_rand(0x19A100, 0x39AA3FF), 10, 36);
?>
This will result in a 5 character random number/string, between: 10000 to zzzzz

Robin Leffmann (25-Dec-2010 02:14)

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

?>

Andrew Moore (10-Aug-2010 05:16)

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

nilesh at itech7 dot com (19-May-2010 08:20)

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;

  }

}
?>

wayne (24-Feb-2010 03:53)

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

james at coretelecom dot co dot uk (08-Feb-2010 11:29)

Makes a random alpha numeric string of a given lenth

<?php
function makePin($lenth =5) {
   
// makes a random alpha numeric string of a given lenth
   
$aZ09 = array_merge(range('A', 'Z'), range('a', 'z'),range(0, 9));
   
$out ='';
    for(
$c=0;$c < $lenth;$c++) {
      
$out .= $aZ09[mt_rand(0,count($aZ09)-1)];
    }
    return
$out;
}
?>

armencho at gmail dot com (05-Feb-2010 09:31)

It should also be noted that 'mt_rand' function is NOT cryptographically secure. This means, among other things, that you cannot depend on it to generate data that is expected to be unpredictable, i.e. truly random. Depending on circumstances, a third person using 'mt_rand' will be able to generate the exact random number (or series of them) you have, which may break your security system.

ISAWHIM (03-Feb-2010 04:46)

This is not trying to dissuade use of this alternative, just trying to expand on the things to "watch-out-for", when using this...

As per the description assumption...
"Many random number generators of older libcs have dubious or unknown characteristics and are slow."

You would elude to the assumption that mt_rand() does not have, "dubious or unknown characteristics". It is obvious that it is faster, but that does not count the additional code required to ensure validity of results, or scope of input value checking.

This function fails horribly, without error, when operating out of the scope of the range. (Key point being, "without error".)

mt_getrandmax() is NOT the max INTEGER size. It is limited to positive numbers from ZERO to your integers largest value. Thus, it is HALF the size of an INTEGER, since integers are SIGNED, but mt_rand can only correctly randomize from ZERO to mt_getrandmax(). (Though, that is not entirely true. It can do negative numbers, if the min/max range/spread is not greater than the value of mt_getrandmax()... sometimes.)

Things to watch-out for... (Sort of negates any speed gains.)

This assumes you "Attempted" to process MIN>=0 and MAX<=mt_getrandmax().

Returning a negative value = RANDOMIZER FAILED
Returning a vlaue higher than mt_getrandmax() = RANDOMIZER FAILED
Returning SAME_NUMBER from more than one call = Possibly RANDOMIZER FAILED
Returning a number <MIN or >MAX = RANDOMIZER FAILED

PHP version 5.2.6 on Apechee 2.0.63 on a Linux server.
Specific instances of failure... (All these still return a value.)
With RAND_MAX reporting that it is '2147483647'.

<?PHP
// Returns negative numbers as if (-2147483647,0)
$z = mt_rand(0,2147483648);

// Returns mostly 1 or negative numbers
$z = mt_rand(-2147483647,2147483647);

// Returns negative numbers, but within range set???
// So much for returning only values from 0 to Max
$z = mt_rand(-2147483647,0);

// Attempt to stay within the range/spread of mt_getrandmax()
// Results are odd, like 180 to 2147478000
$z = mt_rand(2147483647,4294967294);

// Works, but it should not, as the value is not an INT
// Values are converted to floor(x), so range is (0,0)
$z = mt_rand(0.000001,0.9999999);
?>

Code used to test...

<?PHP
// Reports the MAX possible, which is half of an INT's value
echo('RAND_MAX: '.mt_getrandmax());
for(
$i=0;$i<=100000;$i++) {
// RAND_MAX = 2147483647
$z = mt_rand(0,2147483647);
// echo($z.'<BR>'); // Uncomment to see results, lower LOOP values first!
if($z>$high || !isset($high)){$high=$z;}
if(
$z<$low || !isset($low)){$low=$z;}
}
echo(
'HIGH: '.$high.'<BR>LOW: '.$low.'<BR>');
?>

To get a number that is actually in the full range of an INT, you need to make two separate calls, and add them together. Then convert that unsigned INT value into a signed INT value.

armencho at gmail dot com (15-Jan-2010 03:59)

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.

Anonymous (04-Aug-2009 11:45)

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

mark omohundro, ajamyajax dot com (19-Feb-2009 05:13)

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

xphere81 at hotmail dot com (19-Sep-2008 12:08)

@Jonathon

$id_list = range($min, $max);
shuffle($id_list);

This is a faster way to obtain a list of unique id's in a random order.
It's always better to use PHP predefined functions, isn't it? ;)

Also remember that calling mt_rand too many times can downgrade the performance of ANY algorithm.

rst (06-Sep-2008 06:13)

re: rt and euxneks
Simpler:
<?php
printf
( "#%06X\n", mt_rand( 0, 0xFFFFFF ) );
?>

rt (28-Aug-2008 01:14)

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

euxneks at NOSPAMgmail dot com (18-Aug-2008 11:11)

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 :)

keith at ourwebsite dot ca (17-Jul-2008 11:16)

This is how I generate a random colour for backgrounds, graphs, text colour etc.

<?
$total = "9";
$start = "0";

$randcolour    = mt_rand($start, $total);
$randcolour    .= mt_rand($start, $total);
$randcolour    .= mt_rand($start, $total);
$randcolour    .= mt_rand($start, $total);
$randcolour    .= mt_rand($start, $total);
$randcolour    .= mt_rand($start, $total);

?>

<table width="200px" border="0" cellspacing="10" cellpadding="0" bgcolor="#<? echo $randcolour; ?>">
      <tr>
        <td>This table has a random background colour</td>
      </tr>
    </table>

Mark Seecof (06-Jun-2008 07:31)

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.

Rocker (22-May-2008 03:24)

I think this will work faster.

<?php
 
function unique_random($Min,$Max,$num){

   
//this will swap min an max values if $Min>$Max
   
if ($Min>$Max) { $min=$Max; $max=$Min; }
    else {
$min=$Min; $max=$Max; }

   
//this will avoid to enter a number of results greater than possible results
   
if ($num>($max-$min)) $num=($max-$min);

   
$values=array();
   
$result=array();
    for (
$i=$min;$i<=$max;$i++) {
     
$values[]=$i;
    }
    for (
$j=0;$j<$num;$j++){
     
$key=mt_rand(0,count($values)-1);
     
$result[]=$values[$key];
      unset(
$values[$key]);
     
sort($values);
    }
    return
$result;
}
?>

don_knotts at hotmail dot com (22-May-2008 12:58)

I forgot to add a side-note to my post about the unique random number function.  If the array count is more than half of the random number max, the function could take a very long time to process, maybe even go into an infinite loop.  The best way to avoid this is to set the max at twice the array count; i.e. if you want an array of 10 unique random numbers, the maximum random number needs to be at least 20.  For my purposes, I have 50 pictures to choose from, and the function randomly picks 20 of them to display on the webpage, without displaying an image twice.

don_knotts at hotmail dot com (22-May-2008 11:57)

Here is a simple way to get UNIQUE random numbers, because if you are wanting random numbers, say, between 1 and 10, then you will get duplicates very often, so this function takes care of that.  However, for a very large amount of numbers, this could be very slow.  I use this to generate random pictures on a webpage so that I don't get the same picture twice, but it only picks from about 50 pictures.

// **************************************************
// generate UNIQUE random numbers between min and max
// uses the updated mt_rand() php function
// 'min' = minimum random number
// 'max' = maximum random number
// 'count' = how many numbers in the array
// returns array with random numbers
// error msg if count is greater than max
// **************************************************
function generateUniqueRandoms($min, $max, $count)  {
    if($count > $max)  {  // this prevents an infinite loop
        echo "ERROR: The array count is greater than the random number maximum.<br>\n";
        echo "Therefore, it is impossible to build an array of unique random numbers.<br>\n";
        break;
    }   
    $numArray = array();
    for($i = 0; $i < $count; $i++)  {       
        $numArray[$i] = mt_rand($min,$max);         // set random number
        for($j = 0; $j < $count; $j++)                 // for each number, check for duplicates
          if($j != $i)                                 // except for the one you are checking of course
            if($numArray[$i] == $numArray[$j]) {
                $numArray[$i] = mt_rand(1,10);         // if duplicate, generate new random
                $j = 0;                                // go back through and check new number
            }
    }
    return $numArray;
} // end generateUniqueRandoms() ----------------------
// ****************************************************

Jonathon (17-Apr-2008 09:14)

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

geompse at yopmail dot com (29-Mar-2008 12:01)

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().

guilhem at dublin dot ie (25-Mar-2008 09:09)

I'm sorry to say, "andrei at novanetworks dot ro"'s method seems higly unefficient to me. It's good if called few times only, but when most of the numbers have already been used, the function has to loop many times before finding an available option.

When I know I need to call most of the numbers from a range, I create a list of the numbers in the range, get a random index from this list, then return and delete the item of the list at the picked index. More memory usage if called many times, but probably less computation time on average.

andrei at novanetworks dot ro (23-Mar-2008 07:04)

Here's a simple function i've made for generateing unique random numbers. Be carefull, the function will go into an infinite loop if you request more unique numbers then the given range (ex. if you call unic(1, 5) five times it's ok, but the 6'th time it will go into an infinite loop).

$unic_arr = array(); //the array in witch the used numbers are stored.

function unic($min, $max) {
global $unic_arr;
    $rand = mt_rand($min, $max);
    $tf = 1;
    while(true) {
        if(!in_array($rand, $unic_arr)) {
            $tf = 0;
            break;
        }
        else $rand = mt_rand($min, $max);
    }
    array_push($unic_arr, $rand);
    return $rand;
}

//to call the function use:

unic($min, $max); //ex. unic(1000, 9999);

William Leslie (13-Feb-2008 05:24)

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.

dmoree at coker dot edu (29-Jan-2008 03:49)

Here is a simple encryption algorithm I made a few months ago. I was tired of MD5 because they have rainbow tables out that will crack most any MD5 pass. Along with SHA. So encryption algorithms are getting weaker all the time. So here is new one for people to try and crack. So far no one has told me they cracked it. I also use it to generate very random passwords or character segments. Below the function is the random string generator. I tested this algorithm with mt_rand over 10 million iterations without one duplicate string. So use it in good health!

<?php
// Hexi-decimal encryption function
// Returns: 64 character encrypted string
// NOTE: One-Way encryption only
function HexCrypt($string = "", $salt = ""){
    if(
strlen(trim($string)) == 0){
       
$string = " ";
    }
    if(
strlen(trim($salt)) == 0){
       
$salt = " ";
    }
   
$string = $salt.$string.$salt;
   
$lastchar = "";
   
$output = "";
   
$saltlength = "0x".dechex(strlen($salt));

    while(
strlen($output) < 64){
       
$firstchar = "0x".dechex(ord(substr($string, strlen($salt), 1)));
        for(
$i = 0; $i < strlen($string); $i++){
           
$strlength = "0x".dechex($output+$i+3);
            if(
strlen($output) >= 64){
                break(
2);
            }elseif(
$lastchar == ""){
               
$lastchar = "0x".dechex(ord(substr($string, $i, 1)));
            }else{
               
$current = "0x".dechex(ord(substr($string, $i, 1)));
               
$total = ($lastchar * $current) * ($firstchar * $saltlength);
               
$output .= dechex($total);
               
$lastchar = "";
            }
        }
  
        if((
strlen($string)%2) == 1){
           
$total = ($lastchar * $firstchar) * ($firstchar * $saltlength);
           
$output .= dechex($total);
        }

       
$string = $output;
       
$output = "";
    }

    if(
strlen($output) != 0){
       
$output = substr($output, 0, 64);
    }else{
       
$output = substr($string, 0, 64);
    }

    return(
$output);
}

// Generates an 8 character random string
$length = 8;
$string = "";

for(
$i = 0; $i < 32; $i++){
   
$string .= mt_rand(0,9);
}

$start = mt_rand(0, (64-$length));
$salt = substr($string, mt_rand(0,20), 12);
echo
"Random String: ".substr(HexCrypt($string, $salt), $start, $length)."\n";
?>

przemek at sobstel dot org (17-Jan-2008 07:00)

note that OWASP's "Guide to Cryptography" says that a Mersenne Twister (that is used by mt_rand()) "is nowhere near as good as CryptoAPI’s secure random number generation options, OpenSSL, or /dev/urandom which is available on many Unix variants. mt_rand() has been noted to produce the same number on some platforms."

remember that rand() is even weaker.

jfkallen at hotmail dot com (24-Dec-2007 11:37)

mt_rand does not seem to truly generate random numbers.  Im not sure exactly which of the following is more accurate as I was applying the following to sock price deviations which do not follow normal distributions (exactly at least).

If you group observations in 11 buckets such that each bucket represents 10 percentiles and run mt_rand(0,10) 100 times you would expect a simlar result as if you ran 100 iterations of mt_rand(0,100) where each bucket represents 1 1 percentile range.

FYI I think things work slightly better as the range of mt_rand increases.
#$data is a numerical (not associative) array of numbers

sort($data);
$data_size = count($data);
#num_groups is the number of buckets
$num_groups = min($num_groups,$data_size);
$ile_size = $data_size / $num_groups;

//following creates the buckets
$groups[] = $data[0];
for ($i=1;$i<$num_groups;$i++){
  $x = $i * $ile_size;
  $i1 = floor($x);
  $i2 = ceil($x);
  $d1 = $data[$i1];
  $d2 = $data[$i2];
  $var = 1 - ($x-$i1);
  $groups[] = ($d1 * $var) + ($d2 * (1-$var));
}
$groups[] = $data[$data_size-1];

//RUN The Random number generator

$value = array();
for ($j=0;$j<$depth;$j++){
 $t = mt_rand($lower_limit,$upper_limit);
 $value[] = $this->m_groups[$t];
}

//The end result is that as the number of groupas increase the accuracy (ie turue randomness seems to increase proportionally more (up to point).  This is not the way it should work in nature.

root at mantoru dot de (25-Nov-2007 02:47)

I needed a function that returns true with a probability of n%, so here's what I came up with:

<?php
function probability($chance, $out_of = 100) {
   
$random = mt_rand(1, $out_of);
    return
$random <= $chance;
}
?>

A few usage examples:

<?php
/* 50% chance, equal to (bool)mt_rand(0, 1) */
var_dump(probability(50));
/* 0.1% chance, floats will not work -- "1 out of 1000 cases" */
var_dump(probability(1, 1000));
/* Practical example */
if (probability(10)) {
   
$damage *= 1.75; // Critical hit!
}
?>

fabiovh on gmail (13-Nov-2007 02:42)

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 (03-Oct-2007 10:49)

[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

www.mrnaz.com (25-Jul-2007 06:00)

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

rok dot kralj at gmail dot com (16-Jun-2007 08:42)

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

Paul Nolasco (09-May-2007 08:45)

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

Jonathan at jooped dot co dot uk (06-May-2007 04:04)

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

earlsinclair2001 at yahoo dot com (11-Apr-2007 06:46)

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

chagenbu at php dot net (21-Mar-2007 05:18)

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.

(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
?>

Rene at mokiba dot de (10-Mar-2007 10:00)

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 (10-Mar-2007 07:50)

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

heavyraptor (14-Feb-2007 11:26)

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

zolaar at nothanks dot com (08-Feb-2007 06:44)

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.

heavyraptor (12-Dec-2006 05:47)

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 :)

MagicalTux at ooKoo dot org (20-Nov-2006 03:34)

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 (10-Nov-2006 07:35)

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

David (06-Nov-2006 08:40)

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

pHp_n00b (26-Sep-2006 03:00)

<?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();

?>

MagicalTux at ooKoo dot org (25-Aug-2006 01:44)

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

arias at elleondeoro dot com (29-May-2006 10:03)

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!

James (16-Apr-2006 07:02)

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

rollerce at gmail dot com (15-Feb-2006 01:38)

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

ripat at lumadis dot be (08-Nov-2005 04:38)

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.

fahri at konse dot de (08-Oct-2005 05:12)

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

phil [underscore] ozil at hotmail dot com (07-Oct-2005 02:13)

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 at van-steenbeek dot net (03-Oct-2005 03:18)

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.

sean at codeaholics dot com (22-Jul-2005 02:31)

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 (25-May-2005 01:00)

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.

nowhere at where dot net (16-Apr-2005 10:46)

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

mskala at ansuz dot sooke dot bc dot ca (23-Jan-2005 11:47)

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.

timr at onlinehome dot de (13-Aug-2004 12:24)

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)."

(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

tmx at ntlworld dot com (06-Dec-2003 09:26)

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 at yahoo dot com (08-Jul-2003 10:44)

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

jsheets at shadonet dot com (04-Jun-2003 09:49)

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 (02-Mar-2002 08:38)

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

amcclung at stetson dot edu (18-Apr-2001 09:27)

Here's an elegant way of generating a random float value within a certain range:

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

mrdlinux at yahoo dot com (21-Jul-2000 06:02)

And for those who prefer scaling:

mt_rand() / RAND_MAX * (Max - Min) + Min;