1use std::fs::File;
2use std::io::Read;
3
4pub fn fill_bytes(buf: &mut [u8]) {
7 if let Ok(mut f) = File::open("/dev/urandom") {
8 if f.read_exact(buf).is_ok() {
9 return;
10 }
11 }
12
13 use std::time::SystemTime;
15 let mut seed = SystemTime::now()
16 .duration_since(SystemTime::UNIX_EPOCH)
17 .map(|d| d.as_nanos() as u64)
18 .unwrap_or(0xFEEDFACE_DEADC0DE);
19
20 for byte in buf.iter_mut() {
21 seed = seed.wrapping_mul(6364136223846793005).wrapping_add(1442695040888963407);
22 *byte = (seed >> 56) as u8;
23 }
24}
25
26pub fn random_alphanumeric(length: usize) -> String {
28 const CHARS: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
29 let mut bytes = vec![0u8; length];
30 fill_bytes(&mut bytes);
31 let mut s = String::with_capacity(length);
32 for b in bytes {
33 let idx = (b as usize) % CHARS.len();
34 s.push(CHARS[idx] as char);
35 }
36 s
37}
38
39#[derive(Clone, Copy, Debug)]
41pub struct CustomRng;
42
43impl CustomRng {
44 pub fn fill_bytes(&self, buf: &mut [u8]) {
45 fill_bytes(buf);
46 }
47}
48
49pub fn rng() -> CustomRng {
50 CustomRng
51}
52
53pub mod distr {
54 pub struct Alphanumeric;
55
56 pub trait SampleString {
57 fn sample_string(&self, rng: &mut super::CustomRng, length: usize) -> String;
58 }
59
60 impl SampleString for Alphanumeric {
61 fn sample_string(&self, _rng: &mut super::CustomRng, length: usize) -> String {
62 super::random_alphanumeric(length)
63 }
64 }
65}