Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/wasi-common/src/random.rs
1691 views
1
use cap_rand::RngCore;
2
3
/// Implement `WasiRandom` using a deterministic cycle of bytes.
4
pub struct Deterministic {
5
cycle: std::iter::Cycle<std::vec::IntoIter<u8>>,
6
}
7
8
impl Deterministic {
9
pub fn new(bytes: Vec<u8>) -> Self {
10
Deterministic {
11
cycle: bytes.into_iter().cycle(),
12
}
13
}
14
}
15
16
impl RngCore for Deterministic {
17
fn next_u32(&mut self) -> u32 {
18
let b0 = self.cycle.next().expect("infinite sequence");
19
let b1 = self.cycle.next().expect("infinite sequence");
20
let b2 = self.cycle.next().expect("infinite sequence");
21
let b3 = self.cycle.next().expect("infinite sequence");
22
((b0 as u32) << 24) + ((b1 as u32) << 16) + ((b2 as u32) << 8) + (b3 as u32)
23
}
24
fn next_u64(&mut self) -> u64 {
25
let w0 = self.next_u32();
26
let w1 = self.next_u32();
27
((w0 as u64) << 32) + (w1 as u64)
28
}
29
fn fill_bytes(&mut self, buf: &mut [u8]) {
30
for b in buf.iter_mut() {
31
*b = self.cycle.next().expect("infinite sequence");
32
}
33
}
34
fn try_fill_bytes(&mut self, buf: &mut [u8]) -> Result<(), cap_rand::Error> {
35
self.fill_bytes(buf);
36
Ok(())
37
}
38
}
39
40
#[cfg(test)]
41
mod test {
42
use super::*;
43
#[test]
44
fn deterministic() {
45
let mut det = Deterministic::new(vec![1, 2, 3, 4]);
46
let mut buf = vec![0; 1024];
47
det.try_fill_bytes(&mut buf).expect("get randomness");
48
for (ix, b) in buf.iter().enumerate() {
49
assert_eq!(*b, (ix % 4) as u8 + 1)
50
}
51
}
52
}
53
54