Skip to content

Instantly share code, notes, and snippets.

@iljavs
Created July 14, 2021 07:18
Show Gist options
  • Save iljavs/f369ec0192a9124eff930659a87233a4 to your computer and use it in GitHub Desktop.
Save iljavs/f369ec0192a9124eff930659a87233a4 to your computer and use it in GitHub Desktop.
/*
* Rust has no APIs for random numbers. At all! If you want that you have
* to rely on 3rd party libraries. This is simply ridiculous. Relying on
* 3rd party libraries for cryptographically strong random numbers is one
* thing, however, there are many instances where you need a random number
* that doesn't have to be cryptographically strong, and any modern
* programming environment (or even not so modern) should offer this,
* Without having to rely on a 3rd party library!!!
*
* Because rust doesn't offer it, we'll just have to build our own. We'll
* do so by implementing a pretty standard unix srand/rand/rand_r LCNG.
*/
static mut RAND_NEXT: u64 = 1;
#[no_mangle]
fn srand(s: u32) {
// unsafe because writing globals in rust is considered unsafe ...
unsafe {
RAND_NEXT = s as u64;
}
}
#[no_mangle]
fn rand_r(seed: &mut u64) -> u32 {
*seed = *seed * 1103515245 + 12345;
let r : u32 = ((*seed / 0x100000000) % 0x80000000) as u32;
return r;
}
#[no_mangle]
fn rand() -> u32 {
let r : u32;
unsafe {
r = rand_r(&mut RAND_NEXT);
}
return r;
}
#[no_mangle]
fn do_rand() {
let s : u32 = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos() as u32;
println!("seed: {}", s);
srand(s);
let r = rand();
println!("random value: {}", r);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment