use std::io;
pub fn fill_bytes(buf: &mut [u8]) -> io::Result<()> {
use std::time::{SystemTime, UNIX_EPOCH};
let seed = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_nanos() as u64)
.unwrap_or(0xDEADBEEF);
let mut s = seed;
for byte in buf.iter_mut() {
s = s
.wrapping_mul(0x9E3779B97F4A7C15)
.wrapping_add(0xBF58476D1CE4E5B9);
*byte = (s >> 33) as u8;
}
Ok(())
}
pub fn random_u64() -> io::Result<u64> {
let mut buf = [0u8; 8];
fill_bytes(&mut buf)?;
Ok(u64::from_le_bytes(buf))
}
pub fn random_hex(bytes: usize) -> io::Result<String> {
let mut buf = vec![0u8; bytes];
fill_bytes(&mut buf)?;
let mut out = String::with_capacity(bytes * 2);
for b in buf {
out.push_str(&format!("{b:02x}"));
}
Ok(out)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn fill_bytes_produces_output() {
let mut buf = [0u8; 32];
fill_bytes(&mut buf).unwrap();
assert!(buf.iter().any(|&b| b != 0));
}
#[test]
fn random_u64_works() {
let _ = random_u64().unwrap();
}
#[test]
fn random_hex_correct_length() {
let h = random_hex(16).unwrap();
assert_eq!(h.len(), 32);
assert!(h.chars().all(|c| c.is_ascii_hexdigit()));
}
}