# Random Number Generators (RNG) Tomo comes with an `RNG` type (Random Number Generator). This type represents a self-contained piece of data that encapsulates the state of a relatively fast and relatively secure pseudo-random number generator. The current implementation is based on the [ChaCha20 stream cipher,](https://en.wikipedia.org/wiki/Salsa20#ChaCha_variant) inspired by [`arc4random` in OpenBSD.](https://man.openbsd.org/arc4random.3) An `RNG` object can be used for deterministic, repeatable generation of pseudorandom numbers (for example, to be used in a video game for creating seeded levels). The default random number generator for Tomo is called `random` and is, by default, initialized with random data from the operating system when a Tomo program launches. # RNG Functions This documentation provides details on RNG functions available in the API. [Arrays](arrays.md) also have some methods which use RNG values: `array:shuffle()`, `array:shuffled()`, `array:random()`, and `array:sample()`. ## `bool` **Description:** Generate a random boolean value with a given probability. **Signature:** ```tomo func bool(rng: RNG, p: Num = 0.5 -> Bool) ``` **Parameters:** - `rng`: The random number generator to use. - `p`: The probability of returning a `yes` value. Values less than zero and `NaN` values are treated as equal to zero and values larger than zero are treated as equal to one. **Returns:** `yes` with probability `p` and `no` with probability `1-p`. **Example:** ```tomo >> random:bool() = no >> random:bool(1.0) = yes ``` --- ## `byte` **Description:** Generate a random byte with uniform probability. **Signature:** ```tomo func byte(rng: RNG -> Byte) ``` **Parameters:** - `rng`: The random number generator to use. **Returns:** A random byte (0-255). **Example:** ```tomo >> random:byte() = 103[B] ``` --- ## `bytes` **Description:** Generate an array of uniformly random bytes with the given length. **Signature:** ```tomo func bytes(rng: RNG, count: Int -> [Byte]) ``` **Parameters:** - `rng`: The random number generator to use. - `count`: The number of random bytes to return. **Returns:** An array of length `count` random bytes with uniform random distribution (0-255). **Example:** ```tomo >> random:bytes(4) = [135[B], 169[B], 103[B], 212[B]] ``` --- ## `copy` **Description:** Return a copy of a random number generator. This copy will be a parallel version of the given RNG with its own internal state. **Signature:** ```tomo func copy(rng: RNG -> RNG) ``` **Parameters:** - `rng`: The random number generator to copy. **Returns:** A copy of the given RNG. **Example:** ```tomo >> rng := RNG.new([:Byte]) >> copy := rng:copy() >> rng:bytes(10) = [224[B], 102[B], 190[B], 59[B], 251[B], 50[B], 217[B], 170[B], 15[B], 221[B]] # The copy runs in parallel to the original RNG: >> copy:bytes(10) = [224[B], 102[B], 190[B], 59[B], 251[B], 50[B], 217[B], 170[B], 15[B], 221[B]] ``` --- ## `int`, `int64`, `int32`, `int16`, `int8` **Description:** Generate a random integer value with the given range. **Signature:** ```tomo func int(rng: RNG, min: Int, max: Int -> Int) func int64(rng: RNG, min: Int64 = Int64.min, max: Int64 = Int64.max -> Int) func int32(rng: RNG, min: Int32 = Int32.min, max: Int32 = Int32.max -> Int) func int16(rng: RNG, min: Int16 = Int16.min, max: Int16 = Int16.max -> Int) func int8(rng: RNG, min: Int8 = Int8.min, max: Int8 = Int8.max -> Int) ``` **Parameters:** - `rng`: The random number generator to use. - `min`: The minimum value to be returned. - `max`: The maximum value to be returned. **Returns:** An integer uniformly chosen from the range `[min, max]` (inclusive). If `min` is greater than `max`, an error will be raised. **Example:** ```tomo >> random:int(1, 10) = 8 ``` --- ## `new` **Description:** Return a new random number generator. **Signature:** ```tomo func new(seed: [Byte] = (/dev/urandom):read_bytes(40)! -> RNG) ``` **Parameters:** - `seed`: The seed use for the random number generator. A seed length of 40 bytes is recommended. Seed lengths of less than 40 bytes are padded with zeroes. **Returns:** A new random number generator. **Example:** ```tomo >> my_rng := RNG.new([1[B], 2[B], 3[B], 4[B]]) >> my_rng:bool() = yes ``` --- ## `num`, `num32` **Description:** Generate a random floating point value with the given range. **Signature:** ```tomo func num(rng: RNG, min: Num = 0.0, max: Num = 1.0 -> Int) func num32(rng: RNG, min: Num = 0.0_f32, max: Num = 1.0_f32 -> Int) ``` **Parameters:** - `rng`: The random number generator to use. - `min`: The minimum value to be returned. - `max`: The maximum value to be returned. **Returns:** A floating point number uniformly chosen from the range `[min, max]` (inclusive). If `min` is greater than `max`, an error will be raised. **Example:** ```tomo >> random:num(1, 10) = 9.512830439975572 ``` --- ## `set_seed` **Description:** Set the seed for an RNG. **Signature:** ```tomo func set_seed(rng: RNG, seed: [Byte]) ``` **Parameters:** - `rng`: The random number generator to modify. - `seed`: A new seed to re-seed the random number generator with. A seed length of 40 bytes is recommended. Seed lengths of less than 40 bytes are padded with zeroes. **Returns:** Nothing. **Example:** ```tomo random:set_seed((/dev/urandom):read_bytes(40)) ```