@@ -752,36 +752,58 @@ impl<S> SeedRestriction for S where S: private::Sealed + Default + AsMut<[u8]> {
752
752
753
753
/// A random number generator that can be explicitly seeded.
754
754
///
755
- /// There are two subtle differences between `from_rng` and`from_seed` (beyond
756
- /// the obvious): first, that `from_rng` has no reproducibility requirement, and
757
- /// second, that `from_rng` may directly fill internal states larger than
758
- /// `SeedableRng::Seed`, where `from_seed` may need some extra step to expand
759
- /// the input.
755
+ /// Each pseudo-random number generator (PRNG) should implement this.
760
756
pub trait SeedableRng : Sized {
761
- /// Seed type.
757
+ /// Seed type, which is restricted to `u8` arrays with a length of
758
+ /// 4, 8, 12, 16, 24 and 32.
759
+ ///
760
+ /// It is recommended to seed PRNG's with a seed of more than circa
761
+ /// 100 bits, which means an array of `[u8; 12]` or greater to avoid picking
762
+ /// RNG's with partially overlapping periods.
763
+ ///
764
+ /// For cryptographic RNG's a seed of 256 bits is recommended, `[u8; 32]`.
762
765
type Seed : SeedRestriction ;
763
766
764
767
/// Create a new PRNG using the given seed.
765
768
///
766
- /// Each PRNG should implement this.
769
+ /// PRNG implementations are allowed to assume that bits in the seed are
770
+ /// well distributed. That means usually that the number of one and zero
771
+ /// bits are about equal, and values like 0, 1 and (size - 1) are unlikely.
767
772
///
768
- /// Reproducibility is required; that is, a fixed PRNG seeded using this
769
- /// function with a fixed seed should produce the same sequence of output
770
- /// today, and in the future. PRNGs not able to satisfy this should make
771
- /// clear notes in their documentation. It is however not required that this
772
- /// function yield the same state as a reference implementation of the PRNG
773
- /// given equivalent seed; if necessary another constructor should be used.
773
+ /// PRNG implementations are recommended to be reproducible. A PRNG seeded
774
+ /// using this function with a fixed seed should produce the same sequence
775
+ /// of output in the future and on different architectures (with for example
776
+ /// different endianness).
774
777
///
775
- /// It may be expected that bits in the seed are well distributed, i.e. that
776
- /// values like 0, 1 and (size - 1) are unlikely.
778
+ /// It is however not required that this function yield the same state as a
779
+ /// reference implementation of the PRNG given equivalent seed; if necessary
780
+ /// another constructor can be used.
777
781
fn from_seed ( seed : Self :: Seed ) -> Self ;
778
782
779
783
/// Create a new PRNG seeded from another `Rng`.
780
784
///
781
- /// Seeding from a cryptographic generator should be fine. On the other
782
- /// hand, seeding a simple numerical generator from another of the same
783
- /// type sometimes has serious side effects such as effectively cloning the
784
- /// generator.
785
+ /// This is the recommended way to initialize PRNGs. See the `NewSeeded`
786
+ /// trait that provides a convenient `new` method using `from_rng` and a
787
+ /// good entropy source.
788
+ ///
789
+ /// It is recommended to use a good source of randomness to initialize the
790
+ /// PRNG. Otherwise small PRNG's could show statistical bias in the first
791
+ /// couple of results, and possibly not use their entire period well.
792
+ /// Cryptographic PRNG's can be less secure or even insecure when they are
793
+ /// seeded from a non-cryptographic PRNG.
794
+ ///
795
+ /// Examples of good RNG's for seeding are entropy sources like `OsRng` and
796
+ /// `JitterRng`. Also cryptographically secure PRNG's (like `thread_rng`)
797
+ /// can be used without hesitation.
798
+ ///
799
+ /// Seeding a small PRNG from another small PRNG is be possible, but
800
+ /// something to be careful with. An extreme example of how this can go
801
+ /// wrong is seeding an Xorshift RNG from another Xorshift RNG. That will
802
+ /// effectively clone the generator.
803
+ ///
804
+ /// PRNG implementations are allowed to assume that a good RNG is provided
805
+ /// for seeding, and that it is cryptographically secure when appropriate.
806
+ /// There are no reproducibility requirements like endianness conversion.
785
807
fn from_rng < R : Rng > ( mut rng : R ) -> Result < Self , Error > {
786
808
let mut seed = Self :: Seed :: default ( ) ;
787
809
let size = mem:: size_of :: < Self :: Seed > ( ) as usize ;
@@ -886,8 +908,11 @@ pub struct Closed01<F>(pub F);
886
908
/// The standard RNG. This is designed to be efficient on the current
887
909
/// platform.
888
910
///
889
- /// The underlying algorithm is not fixed, thus values from this generator
890
- /// cannot be guaranteed to be reproducible.
911
+ /// Reproducibility of output from this generator is not required, thus future
912
+ /// library versions may use a different internal generator with different
913
+ /// output. Further, this generator may not be portable and can produce
914
+ /// different output depending on the architecture. If you require reproducible
915
+ /// output, use a named RNG, for example `ChaChaRng`.
891
916
#[ derive( Clone , Debug ) ]
892
917
pub struct StdRng ( IsaacWordRng ) ;
893
918
0 commit comments