2020-06-09 15:06:07 +02:00
|
|
|
# Quickstart
|
|
|
|
|
|
|
|
The V `rand` module provides two main ways in which users can generate pseudorandom numbers:
|
|
|
|
|
|
|
|
1. Through top-level functions in the `rand` module.
|
|
|
|
- `import rand` - Import the `rand` module.
|
|
|
|
- `rand.seed(seed_data)` to seed (optional).
|
|
|
|
- Use `rand.int()`, `rand.u32n(max)`, etc.
|
|
|
|
2. Through a generator of choice. The PRNGs are included in their respective submodules.
|
|
|
|
- `import rand.pcg32` - Import the module of the PRNG required.
|
|
|
|
- `mut rng := pcg32.PCG32RNG{}` - Initialize the struct. Note that the **`mut`** is important.
|
|
|
|
- `rng.seed(seed_data)` - optionally seed it with an array of `u32` values.
|
|
|
|
- Use `rng.int()`, `rng.u32n(max)`, etc.
|
|
|
|
|
|
|
|
# General Background
|
|
|
|
|
2020-11-18 18:28:28 +01:00
|
|
|
A PRNG is a Pseudo Random Number Generator.
|
|
|
|
Computers cannot generate truly random numbers without an external source of noise or entropy.
|
|
|
|
We can use algorithms to generate sequences of seemingly random numbers,
|
|
|
|
but their outputs will always be deterministic.
|
|
|
|
This is often useful for simulations that need the same starting seed.
|
2020-06-09 15:06:07 +02:00
|
|
|
|
2020-11-18 18:28:28 +01:00
|
|
|
If you need truly random numbers that are going to be used for cryptography,
|
|
|
|
use the `crypto.rand` module.
|
2020-06-09 15:06:07 +02:00
|
|
|
|
|
|
|
# Guaranteed functions
|
|
|
|
|
2020-11-18 18:28:28 +01:00
|
|
|
The following 21 functions are guaranteed to be supported by `rand`
|
|
|
|
as well as the individual PRNGs.
|
2020-06-09 15:06:07 +02:00
|
|
|
|
2020-11-18 18:28:28 +01:00
|
|
|
- `seed(seed_data)` where `seed_data` is an array of `u32` values.
|
|
|
|
Different generators require different number of bits as the initial seed.
|
|
|
|
The smallest is 32-bits, required by `sys.SysRNG`.
|
|
|
|
Most others require 64-bits or 2 `u32` values.
|
2020-06-09 15:06:07 +02:00
|
|
|
- `u32()`, `u64()`, `int()`, `i64()`, `f32()`, `f64()`
|
|
|
|
- `u32n(max)`, `u64n(max)`, `intn(max)`, `i64n(max)`, `f32n(max)`, `f64n(max)`
|
2020-11-18 18:28:28 +01:00
|
|
|
- `u32_in_range(min, max)`, `u64_in_range(min, max)`, `int_in_range(min, max)`,
|
|
|
|
`i64_in_range(min, max)`, `f32_in_range(min, max)`, `f64_in_range(min, max)`
|
2020-06-09 15:06:07 +02:00
|
|
|
- `int31()`, `int63()`
|
|
|
|
|
|
|
|
# Utility Functions
|
|
|
|
|
2020-11-18 18:28:28 +01:00
|
|
|
All the generators are time-seeded.
|
|
|
|
The helper functions publicly available in `rand.util` module are:
|
2020-06-09 15:06:07 +02:00
|
|
|
|
|
|
|
1. `time_seed_array()` - returns a `[]u32` that can be directly plugged into the `seed()` functions.
|
2020-11-18 18:28:28 +01:00
|
|
|
2. `time_seed_32()` and `time_seed_64()` - 32-bit and 64-bit values respectively
|
|
|
|
that are generated from the current time.
|
2020-06-09 15:06:07 +02:00
|
|
|
|
|
|
|
# Caveats
|
|
|
|
|
2020-11-18 18:28:28 +01:00
|
|
|
Note that the `sys.SysRNG` struct (in the C backend) uses `C.srand()` which sets the seed globally.
|
|
|
|
Consequently, all instances of the RNG will be affected.
|
|
|
|
This problem does not arise for the other RNGs.
|
|
|
|
A workaround (if you _must_ use the libc RNG) is to:
|
2020-06-09 15:06:07 +02:00
|
|
|
|
|
|
|
1. Seed the first instance.
|
|
|
|
2. Generate all values required.
|
|
|
|
3. Seed the second instance.
|
|
|
|
4. Generate all values required.
|
|
|
|
5. And so on...
|