@@ -22,58 +22,20 @@ type Rng = super::xoshiro128plusplus::Xoshiro128PlusPlus;
22
22
/// Note that depending on the application, [`StdRng`] may be faster on many
23
23
/// modern platforms while providing higher-quality randomness. Furthermore,
24
24
/// `SmallRng` is **not** a good choice when:
25
- /// - Security against prediction is important. Use [`StdRng`] instead.
26
- /// - Seeds with many zeros are provided. In such cases, it takes `SmallRng`
27
- /// about 10 samples to produce 0 and 1 bits with equal probability. Either
28
- /// provide seeds with an approximately equal number of 0 and 1 (for example
29
- /// by using [`SeedableRng::from_entropy`] or [`SeedableRng::seed_from_u64`]),
30
- /// or use [`StdRng`] instead.
31
25
///
32
- /// The algorithm is deterministic but should not be considered reproducible
33
- /// due to dependence on platform and possible replacement in future
34
- /// library versions. For a reproducible generator, use a named PRNG from an
35
- /// external crate, e.g. [rand_xoshiro] or [rand_chacha] .
36
- /// Refer also to [The Book](https://rust-random.github.io/book/guide-rngs.html) .
26
+ /// - Portability is required. Its implementation is not fixed. Use a named
27
+ /// generator from an external crate instead, for example [rand_xoshiro] or
28
+ /// [rand_chacha]. Refer also to
29
+ /// [The Book](https://rust-random.github.io/book/guide-rngs.html) .
30
+ /// - Security against prediction is important. Use [`StdRng`] instead .
37
31
///
38
32
/// The PRNG algorithm in `SmallRng` is chosen to be efficient on the current
39
33
/// platform, without consideration for cryptography or security. The size of
40
34
/// its state is much smaller than [`StdRng`]. The current algorithm is
41
35
/// `Xoshiro256PlusPlus` on 64-bit platforms and `Xoshiro128PlusPlus` on 32-bit
42
36
/// platforms. Both are also implemented by the [rand_xoshiro] crate.
43
37
///
44
- /// # Examples
45
- ///
46
- /// Initializing `SmallRng` with a random seed can be done using [`SeedableRng::from_entropy`]:
47
- ///
48
- /// ```
49
- /// use rand::{Rng, SeedableRng};
50
- /// use rand::rngs::SmallRng;
51
- ///
52
- /// // Create small, cheap to initialize and fast RNG with a random seed.
53
- /// // The randomness is supplied by the operating system.
54
- /// let mut small_rng = SmallRng::from_entropy();
55
- /// # let v: u32 = small_rng.gen();
56
- /// ```
57
- ///
58
- /// When initializing a lot of `SmallRng`'s, using [`thread_rng`] can be more
59
- /// efficient:
60
- ///
61
- /// ```
62
- /// use rand::{SeedableRng, thread_rng};
63
- /// use rand::rngs::SmallRng;
64
- ///
65
- /// // Create a big, expensive to initialize and slower, but unpredictable RNG.
66
- /// // This is cached and done only once per thread.
67
- /// let mut thread_rng = thread_rng();
68
- /// // Create small, cheap to initialize and fast RNGs with random seeds.
69
- /// // One can generally assume this won't fail.
70
- /// let rngs: Vec<SmallRng> = (0..10)
71
- /// .map(|_| SmallRng::from_rng(&mut thread_rng).unwrap())
72
- /// .collect();
73
- /// ```
74
- ///
75
38
/// [`StdRng`]: crate::rngs::StdRng
76
- /// [`thread_rng`]: crate::thread_rng
77
39
/// [rand_chacha]: https://crates.io/crates/rand_chacha
78
40
/// [rand_xoshiro]: https://crates.io/crates/rand_xoshiro
79
41
#[ cfg_attr( doc_cfg, doc( cfg( feature = "small_rng" ) ) ) ]
@@ -102,21 +64,53 @@ impl RngCore for SmallRng {
102
64
}
103
65
}
104
66
105
- impl SeedableRng for SmallRng {
106
- type Seed = <Rng as SeedableRng >:: Seed ;
107
-
67
+ impl SmallRng {
68
+ /// Construct an instance seeded from another `Rng`
69
+ ///
70
+ /// We recommend that the source (master) RNG uses a different algorithm
71
+ /// (i.e. is not `SmallRng`) to avoid correlations between the child PRNGs.
72
+ ///
73
+ /// # Example
74
+ /// ```
75
+ /// # use rand::rngs::SmallRng;
76
+ /// let rng = SmallRng::from_rng(rand::thread_rng());
77
+ /// ```
108
78
#[ inline( always) ]
109
- fn from_seed ( seed : Self :: Seed ) -> Self {
110
- SmallRng ( Rng :: from_seed ( seed ) )
79
+ pub fn from_rng < R : RngCore > ( rng : R ) -> Result < Self , Error > {
80
+ Rng :: from_rng ( rng ) . map ( SmallRng )
111
81
}
112
82
83
+ /// Construct an instance seeded from the thread-local RNG
84
+ ///
85
+ /// # Panics
86
+ ///
87
+ /// This method panics only if [`thread_rng`](crate::thread_rng) fails to
88
+ /// initialize.
89
+ #[ cfg( all( feature = "std" , feature = "std_rng" , feature = "getrandom" ) ) ]
113
90
#[ inline( always) ]
114
- fn from_rng < R : RngCore > ( rng : R ) -> Result < Self , Error > {
115
- Rng :: from_rng ( rng) . map ( SmallRng )
91
+ pub fn from_thread_rng ( ) -> Self {
92
+ let mut seed = <Rng as SeedableRng >:: Seed :: default ( ) ;
93
+ crate :: thread_rng ( ) . fill_bytes ( seed. as_mut ( ) ) ;
94
+ SmallRng ( Rng :: from_seed ( seed) )
116
95
}
117
96
97
+ /// Construct an instance from a `u64` seed
98
+ ///
99
+ /// This provides a convenient method of seeding a `SmallRng` from a simple
100
+ /// number by use of another algorithm to mutate and expand the input.
101
+ /// This is suitable for use with low Hamming Weight numbers like 0 and 1.
102
+ ///
103
+ /// **Warning:** the implementation is deterministic but not portable:
104
+ /// output values may differ according to platform and may be changed by a
105
+ /// future version of the library.
106
+ ///
107
+ /// # Example
108
+ /// ```
109
+ /// # use rand::rngs::SmallRng;
110
+ /// let rng = SmallRng::seed_from_u64(1);
111
+ /// ```
118
112
#[ inline( always) ]
119
- fn seed_from_u64 ( state : u64 ) -> Self {
113
+ pub fn seed_from_u64 ( state : u64 ) -> Self {
120
114
SmallRng ( Rng :: seed_from_u64 ( state) )
121
115
}
122
116
}
0 commit comments