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.
14 use core
::default::Default
;
16 use {Rng, SeedableRng}
;
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;
22 /// A wrapper around any RNG which reseeds the underlying RNG after it
23 /// has generated a certain number of random bytes.
25 pub struct ReseedingRng
<R
, Rsdr
> {
27 generation_threshold
: u64,
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
: u64, 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() as u64;
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 rand::{Rng, SeedableRng, StdRng};
107 /// use 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.
136 #[derive(Clone, Copy, Debug)]
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();
144 impl Default
for ReseedWithDefault
{
145 fn default() -> ReseedWithDefault { ReseedWithDefault }
150 use std
::default::Default
;
151 use std
::iter
::repeat
;
152 use super::{ReseedingRng, ReseedWithDefault}
;
153 use {SeedableRng, Rng}
;
159 impl Rng
for Counter
{
160 fn next_u32(&mut self) -> u32 {
166 impl Default
for Counter
{
167 fn default() -> Counter
{
171 impl SeedableRng
<u32> for Counter
{
172 fn reseed(&mut self, seed
: u32) {
175 fn from_seed(seed
: u32) -> Counter
{
179 type MyRng
= ReseedingRng
<Counter
, ReseedWithDefault
>;
182 fn test_reseeding() {
183 let mut rs
= ReseedingRng
::new(Counter {i:0}
, 400, ReseedWithDefault
);
187 assert_eq
!(rs
.next_u32(), i
% 100);
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)));
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();
205 r
.reseed((ReseedWithDefault
, 3));
207 let string2
: String
= r
.gen_ascii_chars().take(100).collect();
208 assert_eq
!(string1
, string2
);
211 const FILL_BYTES_V_LEN
: usize = 13579;
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
);
217 // Sanity test: if we've gotten here, `fill_bytes` has not infinitely
219 assert_eq
!(v
.len(), FILL_BYTES_V_LEN
);
221 // To test that `fill_bytes` actually did something, check that the
222 // average of `v` is not 0.
227 assert
!(sum
/ v
.len() as f64 != 0.0);