mt_rand() - 生成更好的随机数 - php 数学函数
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()快四倍。
如果没有提供可选参数$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
注释
CautionThe 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
图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!