# Random Numbers

> Seeded generators, passed explicitly.

```zig
const std = @import("std");
const expect = std.testing.expect;

test "a seeded generator is reproducible" {
    var prng = std.Random.DefaultPrng.init(42);
    const random = prng.random();

    const first = random.int(u32);

    // Same seed, same sequence: that is what makes tests deterministic.
    var again = std.Random.DefaultPrng.init(42);
    try expect(again.random().int(u32) == first);
}

test "ranges" {
    var prng = std.Random.DefaultPrng.init(0);
    const random = prng.random();

    for (0..100) |_| {
        const die = random.intRangeAtMost(u8, 1, 6); // inclusive
        try expect(die >= 1 and die <= 6);

        const index = random.uintLessThan(usize, 10); // exclusive
        try expect(index < 10);
    }
}

test "floats and booleans" {
    var prng = std.Random.DefaultPrng.init(7);
    const random = prng.random();

    const f = random.float(f64); // [0, 1)
    try expect(f >= 0.0 and f < 1.0);

    _ = random.boolean();
}

test "shuffle a slice" {
    var prng = std.Random.DefaultPrng.init(1);
    var items = [_]u8{ 1, 2, 3, 4, 5 };
    prng.random().shuffle(u8, &items);

    var sum: u32 = 0;
    for (items) |i| sum += i;
    try expect(sum == 15); // same elements, different order
}
```

*Runnable: compiled to WebAssembly and executed by CI against Zig master. (`03-standard-library.random-numbers`)*

There is no global `rand()`. You create a generator, seed it, and pass its
`Random` interface where it is needed: the same explicitness Zig applies to
allocators and I/O.

```zig
var prng = std.Random.DefaultPrng.init(seed);
const random = prng.random();
```

## Seeding

A fixed seed gives a reproducible sequence, which is what you want in tests.
For real unpredictability seed from the OS:

```zig
var prng = std.Random.DefaultPrng.init(seed_from_os);
```

`std.crypto.random` is the cryptographically secure source, and is the one to
use for tokens, keys, or anything an attacker should not predict.
`DefaultPrng` is fast, not secure. Do not use it for secrets.

## Ranges

| Call | Range |
| --- | --- |
| `intRangeAtMost(T, lo, hi)` | `lo..=hi` inclusive |
| `intRangeLessThan(T, lo, hi)` | `lo..hi` |
| `uintLessThan(T, hi)` | `0..hi` |
| `float(T)` | `[0, 1)` |

These handle modulo bias properly. `random.int(u8) % 6` does not, and skews
toward low values.

`shuffle` permutes a slice in place.
