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.
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.
11 //! A wrapper around another RNG that reseeds it after it
12 //! generates a certain number of random bytes.
16 use {Rng, SeedableRng};
17 use core::default::Default;
19 /// How many bytes of entropy the underling RNG is allowed to generate
20 /// before it is reseeded.
21 static DEFAULT_GENERATION_THRESHOLD: uint = 32 * 1024;
23 /// A wrapper around any RNG which reseeds the underlying RNG after it
24 /// has generated a certain number of random bytes.
25 pub struct ReseedingRng<R, Rsdr> {
27 generation_threshold: uint,
28 bytes_generated: uint,
29 /// Controls the behaviour when reseeding the RNG.
33 impl<R: Rng, Rsdr: Reseeder<R>> ReseedingRng<R, Rsdr> {
34 /// Create a new `ReseedingRng` with the given parameters.
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.
41 pub fn new(rng: R, generation_threshold: uint, reseeder: Rsdr) -> ReseedingRng<R,Rsdr> {
44 generation_threshold: generation_threshold,
50 /// Reseed the internal RNG if the number of bytes that have been
51 /// generated exceed the threshold.
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;
61 impl<R: Rng, Rsdr: Reseeder<R>> Rng for ReseedingRng<R, Rsdr> {
62 fn next_u32(&mut self) -> u32 {
63 self.reseed_if_necessary();
64 self.bytes_generated += 4;
68 fn next_u64(&mut self) -> u64 {
69 self.reseed_if_necessary();
70 self.bytes_generated += 8;
74 fn fill_bytes(&mut self, dest: &mut [u8]) {
75 self.reseed_if_necessary();
76 self.bytes_generated += dest.len();
77 self.rng.fill_bytes(dest)
81 impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R> + Default>
82 SeedableRng<(Rsdr, S)> for ReseedingRng<R, Rsdr> {
83 fn reseed(&mut self, (rsdr, seed): (Rsdr, S)) {
84 self.rng.reseed(seed);
86 self.bytes_generated = 0;
89 /// Create a new `ReseedingRng` from the given reseeder and
90 /// seed. This uses a default value for `generation_threshold`.
91 fn from_seed((rsdr, seed): (Rsdr, S)) -> ReseedingRng<R, Rsdr> {
93 rng: SeedableRng::from_seed(seed),
94 generation_threshold: DEFAULT_GENERATION_THRESHOLD,
101 /// Something that can be used to reseed an RNG via `ReseedingRng`.
106 /// use std::rand::{Rng, SeedableRng, StdRng};
107 /// use std::rand::reseeding::{Reseeder, ReseedingRng};
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;
118 /// let rsdr = TickTockReseeder { tick: true };
120 /// let inner = StdRng::new().unwrap();
121 /// let mut rng = ReseedingRng::new(inner, 10, rsdr);
123 /// // this will repeat, because it gets reseeded very regularly.
124 /// let s: String = rng.gen_ascii_chars().take(100).collect();
125 /// println!("{}", s);
129 pub trait Reseeder<R> {
130 /// Reseed the given RNG.
131 fn reseed(&mut self, rng: &mut R);
134 /// Reseed an RNG using a `Default` instance. This reseeds by
135 /// replacing the RNG with the result of a `Default::default` call.
137 pub struct ReseedWithDefault;
139 impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {
140 fn reseed(&mut self, rng: &mut R) {
141 *rng = Default::default();
145 impl Default for ReseedWithDefault {
147 fn default() -> ReseedWithDefault { ReseedWithDefault }
152 use std::prelude::v1::*;
154 use core::iter::order;
155 use super::{ReseedingRng, ReseedWithDefault};
156 use std::default::Default;
157 use {SeedableRng, Rng};
163 impl Rng for Counter {
164 fn next_u32(&mut self) -> u32 {
170 impl Default for Counter {
171 fn default() -> Counter {
175 impl SeedableRng<u32> for Counter {
176 fn reseed(&mut self, seed: u32) {
179 fn from_seed(seed: u32) -> Counter {
183 type MyRng = ReseedingRng<Counter, ReseedWithDefault>;
186 fn test_reseeding() {
187 let mut rs = ReseedingRng::new(Counter {i:0}, 400, ReseedWithDefault);
190 for _ in range(0u, 1000) {
191 assert_eq!(rs.next_u32(), i % 100);
197 fn test_rng_seeded() {
198 let mut ra: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2));
199 let mut rb: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2));
200 assert!(order::equals(ra.gen_ascii_chars().take(100),
201 rb.gen_ascii_chars().take(100)));
205 fn test_rng_reseed() {
206 let mut r: MyRng = SeedableRng::from_seed((ReseedWithDefault, 3));
207 let string1: String = r.gen_ascii_chars().take(100).collect();
209 r.reseed((ReseedWithDefault, 3));
211 let string2: String = r.gen_ascii_chars().take(100).collect();
212 assert_eq!(string1, string2);
215 static FILL_BYTES_V_LEN: uint = 13579;
217 fn test_rng_fill_bytes() {
218 let mut v = Vec::from_elem(FILL_BYTES_V_LEN, 0u8);
219 ::test::rng().fill_bytes(v.as_mut_slice());
221 // Sanity test: if we've gotten here, `fill_bytes` has not infinitely
223 assert_eq!(v.len(), FILL_BYTES_V_LEN);
225 // To test that `fill_bytes` actually did something, check that the
226 // average of `v` is not 0.
231 assert!(sum / v.len() as f64 != 0.0);