~/bend-docscommunity

random.bend relies on unsafe/foreign

raw source on the hub · import bend-kit-random@0.1.0.1/random.bend as Random

Seeded pseudo-random numbers: xoshiro128**, unbiased ranges, floats and shuffles. Not for cryptography.

1 import
import Base

Types

type Rng source · line 9 · raw

Data

xoshiro128** state (https://prng.di.unimi.it/xoshiro128starstar.c). It is never all zero.

Definitions

def rotl source · line 12 · raw

@+x:U32 -> @l:Nat -> @r:Nat -> U32

def mix source · line 16 · raw

@+z:U32 -> U32

splitmix32's output mixer, a bijection on U32.

def seed source · line 22 · raw

@+s:U32 -> Rng

The first four splitmix32 outputs from s. Distinct seeds give distinct states.

def from_state.if source · line 26 · raw

@zero:Bool -> @a:U32 -> @b:U32 -> @c:U32 -> @d:U32 -> Rng

def from_state source · line 34 · raw

@+a:U32 -> @+b:U32 -> @+c:U32 -> @+d:U32 -> Rng

The state (a, b, c, d) as is, to replay a reference stream. All zero gives seed(0).

def next source · line 38 · raw

@r:Rng -> Pair(U32, Rng)

One xoshiro128** step: a uniform U32 and the next state.

def Bool.case source · line 47 · raw

@-A:Type -> @b:Bool -> @t:(@_:Unit -> A) -> @f:(@_:Unit -> A) -> A

def below.go source · line 55 · raw

@fuel:Nat -> @+n:U32 -> @+t:U32 -> @xr:Pair(U32, Rng) -> Pair(U32, Rng)

Rejects draws below t = 2^32 mod n, as OpenBSD's arc4random_uniform does.

def below.if source · line 66 · raw

@small:Bool -> @+n:U32 -> @r:Rng -> Pair(U32, Rng)

def below source · line 75 · raw

@+n:U32 -> @r:Rng -> Pair(U32, Rng)

A uniform U32 in [0, n). Each draw is rejected with odds under 1/2, so after 64 rejections, odds 2^-64, it takes x mod n. For n < 2 it is 0 and r is unchanged.

def range.fin source · line 78 · raw

@lo:U32 -> @xr:Pair(U32, Rng) -> Pair(U32, Rng)

def range source · line 83 · raw

@+lo:U32 -> @hi:U32 -> @r:Rng -> Pair(U32, Rng)

A uniform U32 in [lo, hi). For hi <= lo + 1 it is lo and r is unchanged.

def unit.fin source · line 86 · raw

@xr:Pair(U32, Rng) -> Pair(F32, Rng)

def unit source · line 91 · raw

@r:Rng -> Pair(F32, Rng)

A uniform F32 in [0, 1), from the draw's top 24 bits.

def from_os.fin source · line 156 · raw

@e:Result<&1, &1, Pair(U32, String), Pair(U32, Pair(U32, Pair(U32, U32)))> -> Result<&1, &1, Pair(U32, String), Rng>

def from_os source · line 165 · raw

IO(Result<&1, &1, Pair(U32, String), Rng>)

A generator seeded from OS entropy, for when runs need not repeat.

Templates

template shuffle.fill source · line 94 · raw

@-T:Data -> @xs:List<&2, T> -> @+i:U32 -> @a:Array<T> -> Array<T>

template shuffle.swap.set source · line 101 · raw

@-T:Data -> @+i:U32 -> @+j:U32 -> @xi:T -> @ax:Pair(Array<T>, T) -> Array<T>

template shuffle.swap source · line 105 · raw

@-T:Data -> @+i:U32 -> @+j:U32 -> @ax:Pair(Array<T>, T) -> Array<T>

template shuffle.go source · line 111 · raw

@-T:Data -> @k:Nat -> @+i:U32 -> @a:Array<T> -> @jr:Pair(U32, Rng) -> Pair(Array<T>, Rng)

Fisher-Yates: at slot i, jr is below(i + 1); slot i swaps with slot j. At k = 0, i is 0 and below(1) drew nothing.

template shuffle.read source · line 122 · raw

@-T:Data -> @k:Nat -> @ax:Pair(Array<T>, T) -> @acc:List<&2, T> -> List<&2, T>

Slots [0, k] of the array, with ax the read of slot k, prepended to acc.

template shuffle.fin source · line 131 · raw

@-T:Data -> @+m:U32 -> @ar:Pair(Array<T>, Rng) -> Pair(List<&2, T>, Rng)

template shuffle.run source · line 135 · raw

@-T:Data -> @+h:T -> @+xs:List<&2, T> -> @r:Rng -> Pair(List<&2, T>, Rng)

template shuffle source · line 144 · raw

@-T:Data -> @xs:List<&2, T> -> @r:Rng -> Pair(List<&2, T>, Rng)

A uniform permutation of xs. Every draw is below(i + 1), so a list of n items uses n - 1 draws.

Effects (foreign code)

effect entropy source · line 152 · raw

IO(Result<&1, &1, Pair(U32, String), Pair(U32, Pair(U32, Pair(U32, U32)))>)

16 bytes from the OS (getentropy, or crypto.getRandomValues in JS).

foreign: effs/random.c, effs/random.js