Skip to content

rand #

Description

The V rand module provides two main ways in which users can generate pseudorandom numbers:

Direct Access Through The rand Module

// Import the rand module
import rand

...

// Optionally seed the default generator
rand.seed([u32(3223878742), 1732001562])

...

// Use the top-level functions
rand.u32n(100)!
rand.int() // among others ...

Through A Generator Of Choice

// Import the rand module
import rand
import rand.seed

// Import the module of the generator you want to use
import rand.pcg32

...

// Initialise the generator struct (note the `mut`)
mut rng := &rand.PRNG(pcg32.PCG32RNG{})

// Optionally seed the generator
rng.seed(seed.time_seed_array(pcg32.seed_len))

...

// Use functions of your choice
rng.u32n(100)!
rng.int() // among others ...

More Information

You can change the default generator to a different one. The only requirement is that the generator must implement the PRNG interface. See get_current_rng() and set_rng().

Note > The global PRNG is not thread safe. It is recommended to use separate generators for > separate threads in multi-threaded applications.

There are only a few extra functions that are defined only in this top-level rand module. Otherwise, there is feature parity between the generator functions and the top-level functions.

General Background

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, according to the seed values.

This is often useful for simulations that need the same starting seeds. You may be debugging a program and want to restart it with the same seeds, or you want to verify a working program is still operating identically after compiler or operating system updates.

If you need truly random numbers that are going to be used for cryptography, use the crypto.rand module.

Seeding Functions

All the generators are initialized with time-based seeds. The helper functions publicly available in rand.seed module are:

  1. time_seed_array() - returns a []u32 that can be directly plugged into the seed() functions.
  2. time_seed_32() and time_seed_64() - 32-bit and 64-bit values respectivelythat are generated from the current time.

When composing your own seeds, use "typical" u32 numbers, not small numbers. This is especially important for PRNGs with large state, such as mt19937. You can create random unsigned integers with openssl rand or with v repl as follows:

$ openssl rand -hex 4
e3655862
$ openssl rand -hex 4
97c4b1db
$ v repl
>>> import rand
>>> [rand.u32(),rand.u32()]
[2132382944, 2443871665]

Caveats

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:

  1. Seed the first instance.
  2. Generate all values required.
  3. Seed the second instance.
  4. Generate all values required.
  5. And so on...

Notes

Math interval notation is used throughout the function documentation to denote what numbers ranges include.

An example of [0, max) thus denotes a range with all possible values between 0 and max including 0 but excluding max.

fn ascii #

fn ascii(len int) string

ascii returns a random string of the printable ASCII characters with length len.

fn bernoulli #

fn bernoulli(p f64) !bool

bernoulli returns true with a probability p. Note that 0 <= p <= 1.

fn binomial #

fn binomial(n int, p f64) !int

binomial returns the number of successful trials out of n when the probability of success for each trial is p.

fn bytes #

fn bytes(bytes_needed int) ![]u8

bytes returns a buffer of bytes_needed random bytes

fn choose #

fn choose[T](array []T, k int) ![]T

choose samples k elements from the array without replacement. This means the indices cannot repeat and it restricts the sample size to be less than or equal to the size of the given array. Note that if the array has repeating elements, then the sample may have repeats as well.

fn element #

fn element[T](array []T) !T

element returns a random element from the given array. Note that all the positions in the array have an equal chance of being selected. This means that if the array has repeating elements, then the probability of selecting a particular element is not uniform.

fn exponential #

fn exponential(lambda f64) f64

exponential returns an exponentially distributed random number with the rate parameter lambda. It is expected that lambda is positive.

fn f32 #

fn f32() f32

f32 returns a uniformly distributed 32-bit floating point in range [0, 1).

fn f32_in_range #

fn f32_in_range(min f32, max f32) !f32

f32_in_range returns a uniformly distributed 32-bit floating point in range [min, max).

fn f32cp #

fn f32cp() f32

f32cp returns a uniformly distributed 32-bit floating point in range [0, 1) with full precision mantissa.

fn f32n #

fn f32n(max f32) !f32

f32n returns a uniformly distributed 32-bit floating point in range [0, max).

fn f64 #

fn f64() f64

f64 returns a uniformly distributed 64-bit floating point in range [0, 1).

fn f64_in_range #

fn f64_in_range(min f64, max f64) !f64

f64_in_range returns a uniformly distributed 64-bit floating point in range [min, max).

fn f64cp #

fn f64cp() f64

f64 returns a uniformly distributed 64-bit floating point in range [0, 1) with full precision mantissa.

fn f64n #

fn f64n(max f64) !f64

f64n returns a uniformly distributed 64-bit floating point in range [0, max).

fn fill_buffer_from_set #

fn fill_buffer_from_set(charset string, mut buf []u8)

fill_buffer_from_set fills the array buf with random characters sampled from the given charset

fn get_current_rng #

fn get_current_rng() &PRNG

get_current_rng returns the PRNG instance currently in use. If it is not changed, it will be an instance of wyrand.WyRandRNG.

fn hex #

fn hex(len int) string

hex returns a hexadecimal number of length len containing random characters in range [a-f0-9].

fn i16 #

fn i16() i16

i16 returns a uniformly distributed pseudorandom 16-bit signed (possibly negative) i16.

fn i64 #

fn i64() i64

i64 returns a uniformly distributed pseudorandom 64-bit signed (possibly negative) i64.

fn i64_in_range #

fn i64_in_range(min i64, max i64) !i64

i64_in_range returns a uniformly distributed pseudorandom 64-bit signed i64 in range [min, max).

fn i64n #

fn i64n(max i64) !i64

i64n returns a uniformly distributed pseudorandom 64-bit signed positive i64 in range [0, max).

fn int #

fn int() int

int returns a uniformly distributed pseudorandom 32-bit signed (possibly negative) int.

fn int31 #

fn int31() int

int31 returns a uniformly distributed pseudorandom 31-bit signed positive int.

fn int63 #

fn int63() i64

int63 returns a uniformly distributed pseudorandom 63-bit signed positive i64.

fn int_in_range #

fn int_in_range(min int, max int) !int

int_in_range returns a uniformly distributed pseudorandom 32-bit signed int in range [min, max). Both min and max can be negative, but we must have min < max.

fn intn #

fn intn(max int) !int

intn returns a uniformly distributed pseudorandom 32-bit signed positive int in range [0, max).

fn new_default #

fn new_default(config_ config.PRNGConfigStruct) &PRNG

new_default returns a new instance of the default RNG. If the seed is not provided, the current time will be used to seed the instance.

fn normal #

fn normal(config_ config.NormalConfigStruct) !f64

normal returns a normally distributed pseudorandom f64 with mean mu and standard deviation sigma. By default, mu is 0.0 and sigma is 1.0.

Note: Use normal_pair() instead if you're generating a lot of normal variates.

fn normal_pair #

fn normal_pair(config_ config.NormalConfigStruct) !(f64, f64)

normal_pair returns a pair of normally distributed pseudorandom f64 with mean mu and standard deviation sigma. By default, mu is 0.0 and sigma is 1.0.

fn read #

fn read(mut buf []u8)

read fills in buf a maximum of buf.len random bytes

fn sample #

fn sample[T](array []T, k int) []T

sample samples k elements from the array with replacement. This means the elements can repeat and the size of the sample may exceed the size of the array.

fn seed #

fn seed(seed []u32)

seed sets the given array of u32 values as the seed for the default_rng. The default_rng is an instance of WyRandRNG which takes 2 u32 values. When using a custom RNG, make sure to use the correct number of u32s.

fn set_rng #

fn set_rng(rng &PRNG)

set_rng changes the default RNG from wyrand.WyRandRNG (or whatever the last RNG was) to the one provided by the user. Note that this new RNG must be seeded manually with a constant seed or the seed.time_seed_array() method. Also, it is recommended to store the old RNG in a variable and should be restored if work with the custom RNG is complete. It is not necessary to restore if the program terminates soon afterwards.

fn shuffle #

fn shuffle[T](mut a []T, config_ config.ShuffleConfigStruct) !

shuffle randomly permutates the elements in a. The range for shuffling is optional and the entire array is shuffled by default. Leave the end as 0 to shuffle all elements until the end.

fn shuffle_clone #

fn shuffle_clone[T](a []T, config_ config.ShuffleConfigStruct) ![]T

shuffle_clone returns a random permutation of the elements in a. The permutation is done on a fresh clone of a, so a remains unchanged.

fn string #

fn string(len int) string

string returns a string of length len containing random characters in range [a-zA-Z].

fn string_from_set #

fn string_from_set(charset string, len int) string

string_from_set returns a string of length len containing random characters sampled from the given charset

fn u16 #

fn u16() u16

u16 returns a uniformly distributed pseudorandom 16-bit unsigned positive u16.

fn u32 #

fn u32() u32

u32 returns a uniformly distributed u32 in range [0, 2³²).

fn u32_in_range #

fn u32_in_range(min u32, max u32) !u32

u32_in_range returns a uniformly distributed pseudorandom 32-bit unsigned u32 in range [min, max).

fn u32n #

fn u32n(max u32) !u32

u32n returns a uniformly distributed pseudorandom 32-bit signed positive u32 in range [0, max).

fn u64 #

fn u64() u64

u64 returns a uniformly distributed u64 in range [0, 2⁶⁴).

fn u64_in_range #

fn u64_in_range(min u64, max u64) !u64

u64_in_range returns a uniformly distributed pseudorandom 64-bit unsigned u64 in range [min, max).

fn u64n #

fn u64n(max u64) !u64

u64n returns a uniformly distributed pseudorandom 64-bit signed positive u64 in range [0, max).

fn u8 #

fn u8() u8

u8 returns a uniformly distributed pseudorandom 8-bit unsigned positive u8.

fn ulid #

fn ulid() string

ulid generates an unique lexicographically sortable identifier. See https://github.com/ulid/spec .

Note: ULIDs can leak timing information, if you make them public, because you can infer the rate at which some resource is being created, like users or business transactions. (https://news.ycombinator.com/item?id=14526173)

fn ulid_at_millisecond #

fn ulid_at_millisecond(unix_time_milli u64) string

ulid_at_millisecond does the same as ulid but takes a custom Unix millisecond timestamp via unix_milli.

fn uuid_v4 #

fn uuid_v4() string

uuid_v4 generates a random (v4) UUID See https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)

interface PRNG #

interface PRNG {
mut:
	seed(seed_data []u32)
	u8() u8
	u16() u16
	u32() u32
	u64() u64
	block_size() int
	free()
}

PRNG is a common interface for all PRNGs that can be used seamlessly with the rand modules's API. It defines all the methods that a PRNG (in the vlib or custom made) must implement in order to ensure that all functions can be used with the generator.

fn (PRNG) bytes #

fn (mut rng PRNG) bytes(bytes_needed int) ![]u8

bytes returns a buffer of bytes_needed random bytes

fn (PRNG) read #

fn (mut rng PRNG) read(mut buf []u8)

read fills in buf with a maximum of buf.len random bytes

fn (PRNG) u32n #

fn (mut rng PRNG) u32n(max u32) !u32

u32n returns a uniformly distributed pseudorandom 32-bit signed positive u32 in range [0, max).

fn (PRNG) u64n #

fn (mut rng PRNG) u64n(max u64) !u64

u64n returns a uniformly distributed pseudorandom 64-bit signed positive u64 in range [0, max).

fn (PRNG) u32_in_range #

fn (mut rng PRNG) u32_in_range(min u32, max u32) !u32

u32_in_range returns a uniformly distributed pseudorandom 32-bit unsigned u32 in range [min, max).

fn (PRNG) u64_in_range #

fn (mut rng PRNG) u64_in_range(min u64, max u64) !u64

u64_in_range returns a uniformly distributed pseudorandom 64-bit unsigned u64 in range [min, max).

fn (PRNG) i8 #

fn (mut rng PRNG) i8() i8

i8 returns a (possibly negative) pseudorandom 8-bit i8.

fn (PRNG) i16 #

fn (mut rng PRNG) i16() i16

i16 returns a (possibly negative) pseudorandom 16-bit i16.

fn (PRNG) int #

fn (mut rng PRNG) int() int

int returns a (possibly negative) pseudorandom 32-bit int.

fn (PRNG) i64 #

fn (mut rng PRNG) i64() i64

i64 returns a (possibly negative) pseudorandom 64-bit i64.

fn (PRNG) int31 #

fn (mut rng PRNG) int31() int

int31 returns a positive pseudorandom 31-bit int.

fn (PRNG) int63 #

fn (mut rng PRNG) int63() i64

int63 returns a positive pseudorandom 63-bit i64.

fn (PRNG) intn #

fn (mut rng PRNG) intn(max int) !int

intn returns a pseudorandom int in range [0, max).

fn (PRNG) i64n #

fn (mut rng PRNG) i64n(max i64) !i64

i64n returns a pseudorandom int that lies in [0, max).

fn (PRNG) int_in_range #

fn (mut rng PRNG) int_in_range(min int, max int) !int

int_in_range returns a pseudorandom int in range [min, max).

fn (PRNG) i64_in_range #

fn (mut rng PRNG) i64_in_range(min i64, max i64) !i64

i64_in_range returns a pseudorandom i64 in range [min, max).

fn (PRNG) f32 #

fn (mut rng PRNG) f32() f32

f32 returns a pseudorandom f32 value in range [0, 1) using rng.u32() multiplied by an f64 constant.

fn (PRNG) f32cp #

fn (mut rng PRNG) f32cp() f32

f32cp returns a pseudorandom f32 value in range [0, 1) with full precision (mantissa random between 0 and 1 and the exponent varies as well.) See https://allendowney.com/research/rand/ for background on the method.

fn (PRNG) f64 #

fn (mut rng PRNG) f64() f64

f64 returns a pseudorandom f64 value in range [0, 1) using rng.u64() multiplied by a constant.

fn (PRNG) f64cp #

fn (mut rng PRNG) f64cp() f64

f64cp returns a pseudorandom f64 value in range [0, 1) with full precision (mantissa random between 0 and 1 and the exponent varies as well.) See https://allendowney.com/research/rand/ for background on the method.

fn (PRNG) f32n #

fn (mut rng PRNG) f32n(max f32) !f32

f32n returns a pseudorandom f32 value in range [0, max].

fn (PRNG) f64n #

fn (mut rng PRNG) f64n(max f64) !f64

f64n returns a pseudorandom f64 value in range [0, max].

fn (PRNG) f32_in_range #

fn (mut rng PRNG) f32_in_range(min f32, max f32) !f32

f32_in_range returns a pseudorandom f32 in range [min, max].

fn (PRNG) f64_in_range #

fn (mut rng PRNG) f64_in_range(min f64, max f64) !f64

i64_in_range returns a pseudorandom i64 in range [min, max].

fn (PRNG) ulid #

fn (mut rng PRNG) ulid() string

ulid generates an unique lexicographically sortable identifier. See https://github.com/ulid/spec .

Note: ULIDs can leak timing information, if you make them public, because you can infer the rate at which some resource is being created, like users or business transactions. (https://news.ycombinator.com/item?id=14526173)

fn (PRNG) ulid_at_millisecond #

fn (mut rng PRNG) ulid_at_millisecond(unix_time_milli u64) string

ulid_at_millisecond does the same as ulid but takes a custom Unix millisecond timestamp via unix_milli.

fn (PRNG) string_from_set #

fn (mut rng PRNG) string_from_set(charset string, len int) string

string_from_set returns a string of length len containing random characters sampled from the given charset

fn (PRNG) string #

fn (mut rng PRNG) string(len int) string

string returns a string of length len containing random characters in range [a-zA-Z].

fn (PRNG) hex #

fn (mut rng PRNG) hex(len int) string

hex returns a hexadecimal number of length len containing random characters in range [a-f0-9].

fn (PRNG) ascii #

fn (mut rng PRNG) ascii(len int) string

ascii returns a random string of the printable ASCII characters with length len.

fn (PRNG) fill_buffer_from_set #

fn (mut rng PRNG) fill_buffer_from_set(charset string, mut buf []u8)

fill_buffer_from_set fills the mutable buf with random characters from the given charset

fn (PRNG) bernoulli #

fn (mut rng PRNG) bernoulli(p f64) !bool

bernoulli returns true with a probability p. Note that 0 <= p <= 1.

fn (PRNG) normal #

fn (mut rng PRNG) normal(conf config.NormalConfigStruct) !f64

normal returns a normally distributed pseudorandom f64 with mean mu and standard deviation sigma. By default, mu is 0.0 and sigma is 1.0.

Note: Use normal_pair() instead if you're generating a lot of normal variates.

fn (PRNG) normal_pair #

fn (mut rng PRNG) normal_pair(conf config.NormalConfigStruct) !(f64, f64)

normal_pair returns a pair of normally distributed pseudorandom f64 with mean mu and standard deviation sigma. By default, mu is 0.0 and sigma is 1.0.

fn (PRNG) binomial #

fn (mut rng PRNG) binomial(n int, p f64) !int

binomial returns the number of successful trials out of n when the probability of success for each trial is p.

fn (PRNG) exponential #

fn (mut rng PRNG) exponential(lambda f64) f64

exponential returns an exponentially distributed random number with the rate parameter lambda. It is expected that lambda is positive.

fn (PRNG) shuffle #

fn (mut rng PRNG) shuffle[T](mut a []T, config_ config.ShuffleConfigStruct) !

shuffle randomly permutates the elements in a. The range for shuffling is optional and the entire array is shuffled by default. Leave the end as 0 to shuffle all elements until the end.

fn (PRNG) shuffle_clone #

fn (mut rng PRNG) shuffle_clone[T](a []T, config_ config.ShuffleConfigStruct) ![]T

shuffle_clone returns a random permutation of the elements in a. The permutation is done on a fresh clone of a, so a remains unchanged.

fn (PRNG) choose #

fn (mut rng PRNG) choose[T](array []T, k int) ![]T

choose samples k elements from the array without replacement. This means the indices cannot repeat and it restricts the sample size to be less than or equal to the size of the given array. Note that if the array has repeating elements, then the sample may have repeats as well.

fn (PRNG) element #

fn (mut rng PRNG) element[T](array []T) !T

element returns a random element from the given array. Note that all the positions in the array have an equal chance of being selected. This means that if the array has repeating elements, then the probability of selecting a particular element is not uniform.

fn (PRNG) sample #

fn (mut rng PRNG) sample[T](array []T, k int) []T

sample samples k elements from the array with replacement. This means the elements can repeat and the size of the sample may exceed the size of the array.