REBOL 3 Docs | Guide | Concepts | Functions | Datatypes | Errors |
TOC < Back Next > | Updated: 3-Aug-2010 Edit History |
Returns a random value of the datatype or shuffles series (modifies).
Arguments:
value - Maximum value of result
Refinements:
/seed - Restart or randomize
/secure - Returns a cryptographically secure random number
/only - Pick a random value from a series
See also:
The value passed can be used to restrict the range of the random result. For integers random begins at one, not zero, and is inclusive of the value given. (This conforms to the indexing style used for all series datatypes, allowing random to be used directly with functions like PICK.)
loop 3 [print random 10] 1 5 3
lunch: ["Italian" "French" "Japanese" "American"]
print pick lunch random 4
American
If the given argument is a logic value, the result is actually the same as the result of the expression
even? random 2
Example
loop 4 [print random true] false false false true
loop 2 [print random 1:00:00] 0:12:20 0:48:22
For decimal value the function generates a uniformly distributed random number between zero (inclusive) and the given value (inclusive).
loop 3 [print random 1.0] 0.209417212061865 0.878424991742667 0.93627033045037
Main properties:
RANDOM can also be used on all series datatypes:
print random "abcdef"
dbcafe
print random [1 2 3 4 5]
2 4 5 3 1
In this case RANDOM randomly shuffles the given series "in place", yielding the original series with the same elements, just shuffled. To cut it down, you can use CLEAR:
key: random "abcdefghijklmnopqrstuv0123456789"
clear skip key 6
print key
anfruk
Here's an example password generator. Add more partial words to get more variations:
syls: ["ca" "ru" "lo" "ek" "-" "." "!"]
print rejoin random syls
.!ru-ekcalo
To initialize the random number generator, you can seed it with a value (to repeat the sequence) or the current time to start a unique seed.
random/seed 123 random/seed now
That last line is a good example to provide a fairly random starting value for the random number generator.
The /SECURE variant uses SHA1() of a repeating pattern of the integer bytes (20 bytes total) and it produces cryptographically secure 64-bit random numbers. Cryptographical security means, that it is infeasible to compute the state of the generator from its output. If you don't need to make computing of the generator state infeasible (needed especially when you use the generator to generate passwords, challenges, etc. and want to comply to the FIPS security standards), it is more efficient to use the raw variant (without /SECURE refinement). Even in that case it is not feasible to compute the state, since the state of present generator consists of too many bits to be computable from the output.
The RANDOM function uses a random generator by Donald E. Knuth adjusted to generate 62-bit random integers. Thus, the maximal obtainable random number is 2 to the power of 62 = 4611686018427387904.
If the RANDOM function obtains 0 as an argument, it yields 0. If the argument is a positive integer, the RANDOM function uses rejection, rejecting all "raw randoms" that exceed the largest obtainable multiple of the given VALUE argument. This way, the uniformity of the distribution is assured. In case the given VALUE exceeds the biggest obtainable "raw random", we would have to reject every "raw random" number, so in that case an overflow error is caused (It certainly is an error expecting a bigger random, than the "raw random" maximum).
If the given VALUE is negative, then the generated random integers are in the interval VALUE <= R <= -1.
Uniformly distributed random decimals are generated using the integer output of the Knuth's generator as follows:
tt62: to integer! 2 ** 62
4611686018427387904
random-dec: func [x [decimal!]] [(to decimal! (random tt62) - 1) / tt62 * x]
random/seed 0
random 1.0
0.209417212061865
random/seed 0
random-dec 1.0
0.209417212061865
In case the given decimal VALUE is positive, the generated random deviates are uniformly distributed in the interval 0.0 <= R <= VALUE, i.e. including bounds.
In case the given decimal VALUE is negative, the random deviates are uniformly distributed in the interval VALUE <= R <= 0.0.
Sometimes we need to obtain a uniformly distributed random number R, such that 0.0 < R < 1.0 (i.e. a uniformly distributed random number in the given interval, excluding the bounds). We can get such an R rejecting the bounds as follows:
random/seed 0
until [
r: random 1.0
all [
r !== 0.0
r !== 1.0
]
]
r
0.209417212061865
TOC < Back Next > | REBOL.com - WIP Wiki | Feedback Admin |