WoW:API random: Difference between revisions
(fixed bracket) |
("randseed" -> "randomseed". My bad.) |
||
Line 1: | Line 1: | ||
{{:Lua/Libshortcut|random|math.random}} | |||
=math.random and math.randomseed= | =math.random and math.randomseed= | ||
Line 6: | Line 7: | ||
==Description== | ==Description== | ||
The functions math.random and math.randomseed are interfaces to the simple random generator functions rand and srand that are provided by ANSI C. | The functions math.random and math.randomseed are interfaces to the simple random generator functions rand and srand that are provided by ANSI C. | ||
When called without arguments, math.random returns a pseudo-random real number in the range [0,1). | When called without arguments, math.random returns a pseudo-random real number in the range [0,1). | ||
Line 15: | Line 16: | ||
The math.randomseed function sets a "seed" for the pseudo-random generator: Equal seeds produce equal sequences of numbers. | The math.randomseed function sets a "seed" for the pseudo-random generator: Equal seeds produce equal sequences of numbers. | ||
==On random number generator distribution and security== | |||
The ANSI C rand() function is a Linear Congruential Pseudo-Random Number Generator (LPCRNG). Statistically speaking, LCPRNGs have a fair distribution. However, from a security standpoint they are very weak. | |||
If you depend on random numbers to keep something secret or someone out of something, they only need to see a handful of numbers to be able to guess the next one accurately. In fact, if you output large enough numbers, they only need to see a single number to determine the next one. This is the standard LCPRNG used by Microsoft (written in C): | |||
rng = rng * 214013 + 2531011 | |||
return (rng>>16)&0x7fff; | |||
<b>So, how do I get numbers that are harder to guess?</b> | |||
The easiest way is to reseed the generator as often as possible with ever-changing data that third parties cannot see. | |||
If you are not generating dozens of numbers at once, hooking an event that occurs fairly often (OnUpdate, CHAT_MSG_* events, etc) and doing something like the following to introduce entropy to your generator should work: | |||
math.randomseed(math.random(0,2147483647)+(GetTime()*1000)); | |||
==Example== | ==Example== | ||
Line 36: | Line 53: | ||
The other ranges of the functions are inclusive, and will always return integers. | The other ranges of the functions are inclusive, and will always return integers. | ||
{{ | {{LUA}} |
Revision as of 12:26, 26 May 2006
math.random and math.randomseed
Usage
math.randomseed(s); val = math.random([l, u]);
Description
The functions math.random and math.randomseed are interfaces to the simple random generator functions rand and srand that are provided by ANSI C.
When called without arguments, math.random returns a pseudo-random real number in the range [0,1).
When called with a number n, math.random returns a pseudo-random integer in the range [1,n].
When called with two arguments, l and u, math.random returns a pseudo-random integer in the range [l,u].
The math.randomseed function sets a "seed" for the pseudo-random generator: Equal seeds produce equal sequences of numbers.
On random number generator distribution and security
The ANSI C rand() function is a Linear Congruential Pseudo-Random Number Generator (LPCRNG). Statistically speaking, LCPRNGs have a fair distribution. However, from a security standpoint they are very weak.
If you depend on random numbers to keep something secret or someone out of something, they only need to see a handful of numbers to be able to guess the next one accurately. In fact, if you output large enough numbers, they only need to see a single number to determine the next one. This is the standard LCPRNG used by Microsoft (written in C):
rng = rng * 214013 + 2531011 return (rng>>16)&0x7fff;
So, how do I get numbers that are harder to guess?
The easiest way is to reseed the generator as often as possible with ever-changing data that third parties cannot see.
If you are not generating dozens of numbers at once, hooking an event that occurs fairly often (OnUpdate, CHAT_MSG_* events, etc) and doing something like the following to introduce entropy to your generator should work:
math.randomseed(math.random(0,2147483647)+(GetTime()*1000));
Example
> local x = math.random(); > = x 0.34534 [0 - 1]
> local x = math.random(100); > = x 53 [1 - 100]
> local x = math.random(50, 52); > = x 51 [50 - 52]
Notes
math.randomseed takes any kind of positive number, between 0 and 2^31-1.
The range [0,1) of math.random is exclusive, meaning that you can never get 1.0 exactly. Note that the returned number is not an integer, except the special (very rare) case of 0.
The other ranges of the functions are inclusive, and will always return integers.