4.70. kink/random/PRNG

Pseudo random number generators using xoshiro256** algorithm.

This is a non-blocking deterministic RNG, desgined to be used for Monte Carlo simulation.

xoshiro256** is not cryptographically secure. Thus, if you have to generate such as random nonces, salts, or session ids, use kink/random/CSRNG instead.

4.70.1. type prng

`prng` is a type of pseudo RNGs based on xoshiro256** algorithm.

`prng` is a subtype of `rng`. See kink/random/RNG for `rng` type.

`prng` val is not thread-safe. Thus, use of a single `prng` val from multiple threads must be synchronized.

4.70.1.1. Prng.gen_int(Seed) .gen_bin(Size) .gen_bool

See `rng` type on kink/random/RNG mod for these methods.

4.70.1.2. Prng.state

`state` returns the internal state of the RNG as a 32 bytes `bin` val. The result bin contains at least one non-zero bit.

The result bin can be used as the arg of PRNG.from_state.

Example:

:PRNG.require_from('kink/random/')

:Rng <- PRNG.from_seed(-42)
stdout.print_line(Rng.state.repr)
# => BIN.of(0xfe 0xc8 0x00 0x06 0xdf 0x05 0x42 0x54 0x9b 0x4c 0xba 0xaf 0xb8 0x98 0x7e 0xee 0x00 0xbb 0x49 0xbc 0xa3 0x96 0xee 0xfe 0x9a 0xc8 0xbe 0x5b 0x59 0x28 0xe8 0xf6)

Rng.gen_bool
stdout.print_line(Rng.state.repr)
# => BIN.of(0xff 0x4c 0x04 0xf2 0x3e 0xb5 0xd4 0x4c 0x65 0x3f 0xf3 0x15 0xc4 0x0b 0xd2 0x44 0x8b 0x2c 0x38 0x8a 0x81 0x4f 0xac 0xaa 0x12 0xc3 0x00 0x30 0x80 0x9e 0x9c 0x36)

4.70.2. PRNG.from_seed(Seed)

`from_seed` makes a new `prng` val from the Seed.

Preconditions:

• Seed must be an int num.

The initial state of the RNG is created as follows:

seed_bin := sha256(ASCII representation of Seed.show)
initial state := seed_bin if seed_bin is not all-zero, or otherwise sha256(empty bytes)

Example:

:PRNG.require_from('kink/random/')

:A <- PRNG.from_seed(-42)
stdout.print_line(A.gen_int(100).repr)  # => 62
stdout.print_line(A.gen_int(100).repr)  # => 30
stdout.print_line(A.gen_int(100).repr)  # => 11

:B <- PRNG.from_seed(-42)
stdout.print_line(B.gen_int(100).repr)  # => 62
stdout.print_line(B.gen_int(100).repr)  # => 30
stdout.print_line(B.gen_int(100).repr)  # => 11

:C <- PRNG.from_seed(31)
stdout.print_line(C.gen_int(100).repr)  # => 56
stdout.print_line(C.gen_int(100).repr)  # => 96
stdout.print_line(C.gen_int(100).repr)  # => 97

4.70.3. PRNG.from_state(State)

`from_state` makes a new `prng` val from the initial `State`.

Preconditions:

• `State` must be a `bin` val

• The size of `State` must be 32

• At least one bit of `State` must be 1

The result of Prng.state can be used as the arg of `from_state`.

Example:

:PRNG.require_from('kink/random/')
:BIN.require_from('kink/')

:Initial_state <- BIN.of(
  0xfe 0xc8 0x00 0x06 0xdf 0x05 0x42 0x54 0x9b 0x4c 0xba 0xaf 0xb8 0x98 0x7e 0xee
  0x00 0xbb 0x49 0xbc 0xa3 0x96 0xee 0xfe 0x9a 0xc8 0xbe 0x5b 0x59 0x28 0xe8 0xf6
)
:Rng <- PRNG.from_state(Initial_state)
stdout.print_line(Rng.gen_int(100).repr)  # => 62
stdout.print_line(Rng.gen_int(100).repr)  # => 30
stdout.print_line(Rng.gen_int(100).repr)  # => 11

4.70.4. PRNG.is?(Val)

`is?` returns whether `Val` is a `prng` val.