Skip to main content

wasi_common/
random.rs

1use core::convert::Infallible;
2use rand::{Rng, TryRng};
3
4/// Implement `WasiRandom` using a deterministic cycle of bytes.
5pub struct Deterministic {
6    cycle: std::iter::Cycle<std::vec::IntoIter<u8>>,
7}
8
9impl Deterministic {
10    pub fn new(bytes: Vec<u8>) -> Self {
11        Deterministic {
12            cycle: bytes.into_iter().cycle(),
13        }
14    }
15}
16
17impl TryRng for Deterministic {
18    type Error = Infallible;
19    fn try_next_u32(&mut self) -> Result<u32, Infallible> {
20        let b0 = self.cycle.next().expect("infinite sequence");
21        let b1 = self.cycle.next().expect("infinite sequence");
22        let b2 = self.cycle.next().expect("infinite sequence");
23        let b3 = self.cycle.next().expect("infinite sequence");
24        Ok(((b0 as u32) << 24) + ((b1 as u32) << 16) + ((b2 as u32) << 8) + (b3 as u32))
25    }
26    fn try_next_u64(&mut self) -> Result<u64, Infallible> {
27        let w0 = self.next_u32();
28        let w1 = self.next_u32();
29        Ok(((w0 as u64) << 32) + (w1 as u64))
30    }
31    fn try_fill_bytes(&mut self, buf: &mut [u8]) -> Result<(), Infallible> {
32        for b in buf.iter_mut() {
33            *b = self.cycle.next().expect("infinite sequence");
34        }
35        Ok(())
36    }
37}
38
39#[cfg(test)]
40mod test {
41    use super::*;
42    #[test]
43    fn deterministic() {
44        let mut det = Deterministic::new(vec![1, 2, 3, 4]);
45        let mut buf = vec![0; 1024];
46        det.try_fill_bytes(&mut buf).expect("get randomness");
47        for (ix, b) in buf.iter().enumerate() {
48            assert_eq!(*b, (ix % 4) as u8 + 1)
49        }
50    }
51}