use std::fs::File; use std::io::Read; use std::sync::Mutex; use std::time::SystemTime; static STATE: Mutex = Mutex::new(0); fn seed_urandom() -> Option<()> { let mut f = File::open("/dev/urandom").ok()?; let mut bytes = [0; 8]; f.read_exact(&mut bytes).ok()?; *STATE.lock().unwrap() = u64::from_ne_bytes(bytes); return Some(()); } fn seed_time() -> Option<()> { let n = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) .ok()?; *STATE.lock().unwrap() = n.as_nanos() as u64; return Some(()); } pub fn seed() -> Option<()> { match seed_urandom() { Some(()) => return Some(()), None => (), } match seed_time() { Some(()) => return Some(()), None => (), } return None; } fn mix(s: &mut u64) { // https://en.wikipedia.org/wiki/Linear_congruential_generator *s = s.wrapping_mul(6364136223846793005).wrapping_add(1); } pub fn random() -> f64 { let mut s = STATE.lock().unwrap(); mix(&mut s); return (*s >> 32) as f64 / 4294967296.; }