百科狗-知识改变命运!
--

mt_rand() - 生成更好的随机数 - php 数学函数

乐乐1年前 (2023-11-21)阅读数 19#技术干货
文章标签随机数

mt_rand()

(PHP 4, PHP 5, PHP 7)

生成更好的随机数

说明

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

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

mt_rand() - 生成更好的随机数 - php 数学函数

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

参数

$min

可选的、返回的最小值(默认:0)

$max

可选的、返回的最大值(默认:mt_getrandmax())

返回值

返回$min(或者 0)到$max(或者是到mt_getrandmax(),包含这个值)之间的随机整数。

更新日志

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

范例

Example #1mt_rand()例子

以上例程的输出类似于:

1604716014
1478613278
6

注释

Caution

The distribution ofmt_rand()return values is biased towards even numbers on 64-bit builds of PHP when$maxis beyond2^32.

参见

  • mt_srand() 播下一个更好的随机数发生器种子
  • mt_getrandmax() 显示随机数的最大可能值
  • rand() 产生一个随机整数
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:

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)
mt_rand is not calculated by Mersenne Twister.
https://github.com/php/php-src/commit/a0724d30817600540946b41e40f4cfc2a0c30f80
To quickly build a human-readable random string for a captcha per example :

Note that I have removed q and y from $chars to avoid readability problems.
The seed is the PID + LCG (https://github.com/php/php-src/search?q=GENERATE_SEED&unscoped_q=GENERATE_SEED)
rand() comes from the libc, and mt_rand() is internal to PHP. So the differences vary with their respective versions.
On a 64b Debian Stretch with PHP 5.6.21, there is no visible difference: http://oi64.tinypic.com/2nkqas6.jpg
This image compares the two functions. In the top half with random points, in the lower half with random intensity on each point. This is totally different from what was obtained 4 years ago in another note, with an unknown environment.
Here is the code for this visual comparison. 
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.
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:

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.
Allows characters 0-9, a-z
Weighted (and tested) ok. 
a better (and likely faster) way to generate a random 6-digit hex string:

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.
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): 
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. 
I wrote another function to get a random float, if its not precise enougth jut add some '0' to the $mul parameter.

I made following tests: 
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().
With PHP 5.3.3, we're seeing odd behavior on 32 bit Linux.
This works fine on 64 bit Linux: 

but on our 32 bit Linux development server, it's always yielding "00000000". 
On that same machine, this: 
 
seems to always yield either 00000000 or a number in the range fffffff2 to ffffffff. This: 
 
gives numbers where the last two digits vary, and so on through at least 0xF0000000. 
However, this: 

seems to be well-behaved.
The moral? On 32 bit systems, be careful about crossing the signed number boundary, 0x7FFFFFFF.
Another generic random string function, but very small and fast. 
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
/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.
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. 
Fast, pseudo-random binary data generation using mt_rand(): 
If you need a predictable set of numbers for a given seed, you may use the following Pure-PHP implementation of a Mersenne Twister 
A class to generate 99.5% unqiue strings. I found that there is only one or two characters common between two subsequent strings. 
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.

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.
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. 
Re: euxneks at NOSPAMgmail dot com
You might also want to add STR_PAD_LEFT and have: 
Re: keith at ourwebsite dot ca
Here's another way to do it, in one line :)

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

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

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)