Created
July 14, 2021 07:18
-
-
Save iljavs/f369ec0192a9124eff930659a87233a4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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