Pseudo-random number needed

Can anyone please point me to sample code that implements a Pseudo Random Number? I'm writing an automated test, so I can't use a genuine random number, I need to create a generator with a seed so a predictable, repeatable value will result.

I did do my due diligence before posting, I did research and googled and read docs, but I guess I'm having trouble understanding Rust's way of documenting things. I read all about "Trait rand_core::SeedableRng" but I don't see how to use it. There's even sample code under the heading "Implementing SeedableRng for RNGs with large seeds", but again, how is it used? There is no line that bears any resemblance to genuine random numbers, such as:
let n: u32 = rng.gen_range(0, 90).

I didn't come here without trying a few things first, but my attempt to add a "main" to the code provided was not a fruitful approach.

use rand_core::SeedableRng;

const N: usize = 64;
pub struct MyRngSeed(pub [u8; N]);
pub struct MyRng(MyRngSeed);

pub fn main() {
    let same_seed = MyRngSeed( [42 as u8; 64] );
    let mut pseudo_rng = SeedableRng::from_seed( same_seed );
    let rnd_nmr= pseudo_rng.gen_range(0, 90);
    println!("{}", rnd_nmr);
}

impl Default for MyRngSeed {
    fn default() -> MyRngSeed {
        MyRngSeed([0; N])
    }
}

impl AsMut<[u8]> for MyRngSeed {
    fn as_mut(&mut self) -> &mut [u8] {
        &mut self.0
    }
}

impl SeedableRng for MyRng {
    type Seed = MyRngSeed;

    fn from_seed(seed: MyRngSeed) -> MyRng {
        MyRng(seed)
    }
}

This obviously won't work because there is no "gen_range" function available.
Normally I just ask to be pointed to the right documentation, but it would not help me in this case, since I don't understand the documentation. I even found the "Rust Rand Book" which seemed promising, but I found it to be quite heavy on theory and quite light on syntax, so that was not the answer.

I suppose I'll just hard-code a number in my test in the end, but I wanted to use Pseudo-random. Any help would be appreciated.

Rng::gen_range
you have to pull that Trait into scope to use it:

use rand::Rng;

The rand crate provides many rngs to choose from, why implement your own?

And yes, Rust isn't the easiest language. The Rust Book only describes the basics, and you are unlikely to have much luck without understanding them.

2 Likes

The problem might be that there are two sides to this, docs which explain how implement a random number generator and docs that explain how to use a random number generator. The rand_core crate is for the first case, if you wanted to say expose a new source of randomness then this would be a good crate to use. The crate level docs explain how to do that: https://docs.rs/rand_core/

These trait definitions are in their own crate so that if someone wants to make a new random number generator, they don’t need to unnecessarily include some other random number generator with their new one.

To actually generate random numbers with an existing random number generator, take a look at the rand crate instead: https://docs.rs/rand/

For a unit test, you probably want to ensure that the same random numbers are generated every time, regardless of which OS/hardware is being used, the rand_pcg makes that promise:

any change affecting the output given a fixed seed would be considered a breaking change to the crate

This is another crate from the overarching Rand project: https://github.com/rust-random/rand

To use it, you'll need to use the Pcg32 type which actually generates the pseudo random numbers, and a couple of traits which provide easy-to-use methods for it:

use rand::{SeedableRng, Rng};
use rand_pcg::Pcg32;

fn main() {
    let mut rng = Pcg32::seed_from_u64(42);
    for _ in 0..10 {
        let x: u32 = rng.gen();
        println!("{}", x);
    }
}

Playground link

2 Likes

Thanks very much for the help, that pushes me forward by several leaps. I'm applying it and I appreciate the advice.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.