1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT 2 // file at the top-level directory of this distribution and at 3 // http://rust-lang.org/COPYRIGHT. 4 // 5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or 6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license 7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your 8 // option. This file may not be copied, modified, or distributed 9 // except according to those terms. 10 11 //! A wrapper around another RNG that reseeds it after it 12 //! generates a certain number of random bytes. 13 14 use std::default::Default; 15 16 use {Rng, SeedableRng}; 17 18 /// How many bytes of entropy the underling RNG is allowed to generate 19 /// before it is reseeded 20 const DEFAULT_GENERATION_THRESHOLD: u64 = 32 * 1024; 21 22 /// A wrapper around any RNG which reseeds the underlying RNG after it 23 /// has generated a certain number of random bytes. 24 #[derive(Debug)] 25 pub struct ReseedingRng<R, Rsdr> { 26 rng: R, 27 generation_threshold: u64, 28 bytes_generated: u64, 29 /// Controls the behaviour when reseeding the RNG. 30 pub reseeder: Rsdr, 31 } 32 33 impl<R: Rng, Rsdr: Reseeder<R>> ReseedingRng<R, Rsdr> { 34 /// Create a new `ReseedingRng` with the given parameters. 35 /// 36 /// # Arguments 37 /// 38 /// * `rng`: the random number generator to use. 39 /// * `generation_threshold`: the number of bytes of entropy at which to reseed the RNG. 40 /// * `reseeder`: the reseeding object to use. new(rng: R, generation_threshold: u64, reseeder: Rsdr) -> ReseedingRng<R,Rsdr>41 pub fn new(rng: R, generation_threshold: u64, reseeder: Rsdr) -> ReseedingRng<R,Rsdr> { 42 ReseedingRng { 43 rng: rng, 44 generation_threshold: generation_threshold, 45 bytes_generated: 0, 46 reseeder: reseeder 47 } 48 } 49 50 /// Reseed the internal RNG if the number of bytes that have been 51 /// generated exceed the threshold. reseed_if_necessary(&mut self)52 pub fn reseed_if_necessary(&mut self) { 53 if self.bytes_generated >= self.generation_threshold { 54 self.reseeder.reseed(&mut self.rng); 55 self.bytes_generated = 0; 56 } 57 } 58 } 59 60 61 impl<R: Rng, Rsdr: Reseeder<R>> Rng for ReseedingRng<R, Rsdr> { next_u32(&mut self) -> u3262 fn next_u32(&mut self) -> u32 { 63 self.reseed_if_necessary(); 64 self.bytes_generated += 4; 65 self.rng.next_u32() 66 } 67 next_u64(&mut self) -> u6468 fn next_u64(&mut self) -> u64 { 69 self.reseed_if_necessary(); 70 self.bytes_generated += 8; 71 self.rng.next_u64() 72 } 73 fill_bytes(&mut self, dest: &mut [u8])74 fn fill_bytes(&mut self, dest: &mut [u8]) { 75 self.reseed_if_necessary(); 76 self.bytes_generated += dest.len() as u64; 77 self.rng.fill_bytes(dest) 78 } 79 } 80 81 impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R> + Default> 82 SeedableRng<(Rsdr, S)> for ReseedingRng<R, Rsdr> { reseed(&mut self, (rsdr, seed): (Rsdr, S))83 fn reseed(&mut self, (rsdr, seed): (Rsdr, S)) { 84 self.rng.reseed(seed); 85 self.reseeder = rsdr; 86 self.bytes_generated = 0; 87 } 88 89 /// Create a new `ReseedingRng` from the given reseeder and 90 /// seed. This uses a default value for `generation_threshold`. from_seed((rsdr, seed): (Rsdr, S)) -> ReseedingRng<R, Rsdr>91 fn from_seed((rsdr, seed): (Rsdr, S)) -> ReseedingRng<R, Rsdr> { 92 ReseedingRng { 93 rng: SeedableRng::from_seed(seed), 94 generation_threshold: DEFAULT_GENERATION_THRESHOLD, 95 bytes_generated: 0, 96 reseeder: rsdr 97 } 98 } 99 } 100 101 /// Something that can be used to reseed an RNG via `ReseedingRng`. 102 /// 103 /// # Example 104 /// 105 /// ```rust 106 /// use rand::{Rng, SeedableRng, StdRng}; 107 /// use rand::reseeding::{Reseeder, ReseedingRng}; 108 /// 109 /// struct TickTockReseeder { tick: bool } 110 /// impl Reseeder<StdRng> for TickTockReseeder { 111 /// fn reseed(&mut self, rng: &mut StdRng) { 112 /// let val = if self.tick {0} else {1}; 113 /// rng.reseed(&[val]); 114 /// self.tick = !self.tick; 115 /// } 116 /// } 117 /// fn main() { 118 /// let rsdr = TickTockReseeder { tick: true }; 119 /// 120 /// let inner = StdRng::new().unwrap(); 121 /// let mut rng = ReseedingRng::new(inner, 10, rsdr); 122 /// 123 /// // this will repeat, because it gets reseeded very regularly. 124 /// let s: String = rng.gen_ascii_chars().take(100).collect(); 125 /// println!("{}", s); 126 /// } 127 /// 128 /// ``` 129 pub trait Reseeder<R> { 130 /// Reseed the given RNG. reseed(&mut self, rng: &mut R)131 fn reseed(&mut self, rng: &mut R); 132 } 133 134 /// Reseed an RNG using a `Default` instance. This reseeds by 135 /// replacing the RNG with the result of a `Default::default` call. 136 #[derive(Clone, Copy, Debug)] 137 pub struct ReseedWithDefault; 138 139 impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault { reseed(&mut self, rng: &mut R)140 fn reseed(&mut self, rng: &mut R) { 141 *rng = Default::default(); 142 } 143 } 144 impl Default for ReseedWithDefault { default() -> ReseedWithDefault145 fn default() -> ReseedWithDefault { ReseedWithDefault } 146 } 147 148 #[cfg(test)] 149 mod test { 150 use std::default::Default; 151 use std::iter::repeat; 152 use super::{ReseedingRng, ReseedWithDefault}; 153 use {SeedableRng, Rng}; 154 155 struct Counter { 156 i: u32 157 } 158 159 impl Rng for Counter { next_u32(&mut self) -> u32160 fn next_u32(&mut self) -> u32 { 161 self.i += 1; 162 // very random 163 self.i - 1 164 } 165 } 166 impl Default for Counter { default() -> Counter167 fn default() -> Counter { 168 Counter { i: 0 } 169 } 170 } 171 impl SeedableRng<u32> for Counter { reseed(&mut self, seed: u32)172 fn reseed(&mut self, seed: u32) { 173 self.i = seed; 174 } from_seed(seed: u32) -> Counter175 fn from_seed(seed: u32) -> Counter { 176 Counter { i: seed } 177 } 178 } 179 type MyRng = ReseedingRng<Counter, ReseedWithDefault>; 180 181 #[test] test_reseeding()182 fn test_reseeding() { 183 let mut rs = ReseedingRng::new(Counter {i:0}, 400, ReseedWithDefault); 184 185 let mut i = 0; 186 for _ in 0..1000 { 187 assert_eq!(rs.next_u32(), i % 100); 188 i += 1; 189 } 190 } 191 192 #[test] test_rng_seeded()193 fn test_rng_seeded() { 194 let mut ra: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2)); 195 let mut rb: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2)); 196 assert!(::test::iter_eq(ra.gen_ascii_chars().take(100), 197 rb.gen_ascii_chars().take(100))); 198 } 199 200 #[test] test_rng_reseed()201 fn test_rng_reseed() { 202 let mut r: MyRng = SeedableRng::from_seed((ReseedWithDefault, 3)); 203 let string1: String = r.gen_ascii_chars().take(100).collect(); 204 205 r.reseed((ReseedWithDefault, 3)); 206 207 let string2: String = r.gen_ascii_chars().take(100).collect(); 208 assert_eq!(string1, string2); 209 } 210 211 const FILL_BYTES_V_LEN: usize = 13579; 212 #[test] test_rng_fill_bytes()213 fn test_rng_fill_bytes() { 214 let mut v = repeat(0u8).take(FILL_BYTES_V_LEN).collect::<Vec<_>>(); 215 ::test::rng().fill_bytes(&mut v); 216 217 // Sanity test: if we've gotten here, `fill_bytes` has not infinitely 218 // recursed. 219 assert_eq!(v.len(), FILL_BYTES_V_LEN); 220 221 // To test that `fill_bytes` actually did something, check that the 222 // average of `v` is not 0. 223 let mut sum = 0.0; 224 for &x in v.iter() { 225 sum += x as f64; 226 } 227 assert!(sum / v.len() as f64 != 0.0); 228 } 229 } 230