summaryrefslogtreecommitdiffstats
path: root/src/rand.rs
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2023-07-21 21:41:37 -0700
committerRose Hogenson <rosehogenson@posteo.net>2023-07-21 21:41:37 -0700
commitb5caf80b8f18fcafca3ff697f219070825620695 (patch)
treeabd313556c855a109db531d04d5dc4bdf6071fba /src/rand.rs
parent8b51759dc9b26eb9d9e9f94807d7e85a41fbf555 (diff)
downloadstallman-shooter-b5caf80b8f18fcafca3ff697f219070825620695.tar.zst
Remove dependency on the rand crate.
I don't need a dependency to generate random numbers. I know how to generate random numbers.
Diffstat (limited to 'src/rand.rs')
-rw-r--r--src/rand.rs47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/rand.rs b/src/rand.rs
new file mode 100644
index 0000000..404e115
--- /dev/null
+++ b/src/rand.rs
@@ -0,0 +1,47 @@
+use std::fs::File;
+use std::io::Read;
+use std::sync::Mutex;
+use std::time::SystemTime;
+
+static STATE: Mutex<u64> = 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.;
+}