#random #xor #length #byte-length #counter

xor_rand

An arbitrary byte length, counter based PRNG crate

16 releases

0.1.3400 Oct 3, 2021
0.1.3355 Oct 3, 2021
0.1.3000 Sep 29, 2021

#1147 in Algorithms

Download history 4/week @ 2024-02-26 228/week @ 2024-04-01

228 downloads per month

AGPL-3.0-or-later

5KB
71 lines

Arbitrary state length, additive xor based PRNG:

How to use this library:

It is recommended to keep one global state, initialized once with a state length greater than 4 bytes, and to pass it by mutable reference when fetching random numbers.

Here is some source code explaining the simpler aspects, more functionality such as iterators can be found in the source code.

use std::time::{SystemTime, UNIX_EPOCH};
use xor_rand::XorRand;

fn main() {
    // Default creation, 8 bytes state size
    // let mut prng = XorRand::default();

    // Creating prng, 0-2 is bad, 3-4 ok, 5-8 good, 9+ excellent
    let mut prng = XorRand::new(16);

    // Seeding prng
    prng.seed("Hello, world!".as_bytes());
    let number = i64::from_be_bytes(prng.next_bytes());
    println!("Well this was unexpected: {}", number);

    // Seeding with system time
    let now = SystemTime::now();
    let since_epoch = now.duration_since(UNIX_EPOCH).expect("Time went backwards");
    let seed = since_epoch.as_micros();
    prng.seed(&seed.to_be_bytes());

    // Simple byte use
    println!(
        "The first byte this prng should output: {}",
        prng.next_byte()
    );

    // Simple integer use
    for _ in 0..10 {
        let random_num = u128::from_be_bytes(prng.next_bytes());
        println!("Here is a pseudo random number: {}!", random_num);
    }

    // Passing to functions
    roll_dice(&mut prng);

    // An example of how to NOT get uniform floats.
    // Instead, get a uniform integer and cast to a float, divide to get required precision.
    println!(
        "NON UNIFORM RANDOMNESS: {:+e}",
        f64::from_be_bytes(prng.next_bytes())
    );
}

fn roll_dice(prng: &mut XorRand) {
    let dice_roll = u32::from_le_bytes(prng.next_bytes()) % 6;
    println!("You rolled a {}!", dice_roll + 1);
}

Where this xor based PRNG came from:

I was messing around with state mixing, found something which worked supprising well, and this came out of it. It was too good not to share with the world.

No runtime deps