250
250
#[ cfg( feature="std" ) ] extern crate std as core;
251
251
#[ cfg( all( feature = "alloc" , not( feature="std" ) ) ) ] extern crate alloc;
252
252
253
- use core:: marker;
254
- use core:: mem;
253
+ use core:: { marker, mem, slice} ;
255
254
#[ cfg( feature="std" ) ] use std:: cell:: RefCell ;
256
255
#[ cfg( feature="std" ) ] use std:: rc:: Rc ;
257
256
#[ cfg( all( feature="alloc" , not( feature="std" ) ) ) ] use alloc:: boxed:: Box ;
@@ -732,36 +731,66 @@ impl<'a, R: Rng> Iterator for AsciiGenerator<'a, R> {
732
731
}
733
732
}
734
733
735
- /// A random number generator that can be explicitly seeded to produce
736
- /// the same stream of randomness multiple times.
737
- pub trait SeedableRng < Seed > : Rng {
738
- /// Reseed an RNG with the given seed.
734
+ mod private {
735
+ pub trait Sealed { }
736
+ impl Sealed for [ u8 ; 4 ] { }
737
+ impl Sealed for [ u8 ; 8 ] { }
738
+ impl Sealed for [ u8 ; 12 ] { }
739
+ impl Sealed for [ u8 ; 16 ] { }
740
+ impl Sealed for [ u8 ; 24 ] { }
741
+ impl Sealed for [ u8 ; 32 ] { }
742
+ }
743
+
744
+ /// The seed type is restricted to these types. This trait is sealed to prevent
745
+ /// user-extension.
746
+ ///
747
+ /// Use of byte-arrays avoids endianness issues. We may extend this to allow
748
+ /// byte arrays of other lengths in the future.
749
+ pub trait SeedRestriction : private:: Sealed + Default + AsMut < [ u8 ] > { }
750
+ impl < S > SeedRestriction for S where S : private:: Sealed + Default + AsMut < [ u8 ] > { }
751
+
752
+ /// A random number generator that can be explicitly seeded.
753
+ ///
754
+ /// There are two subtle differences between `from_rng` and`from_seed` (beyond
755
+ /// the obvious): first, that `from_rng` has no reproducibility requirement, and
756
+ /// second, that `from_rng` may directly fill internal states larger than
757
+ /// `SeedableRng::Seed`, where `from_seed` may need some extra step to expand
758
+ /// the input.
759
+ pub trait SeedableRng : Sized {
760
+ /// Seed type.
761
+ type Seed : SeedRestriction ;
762
+
763
+ /// Create a new PRNG using the given seed.
739
764
///
740
- /// # Example
765
+ /// Each PRNG should implement this.
741
766
///
742
- /// ```rust
743
- /// use rand::{Rng, SeedableRng, StdRng};
767
+ /// Reproducibility is required; that is, a fixed PRNG seeded using this
768
+ /// function with a fixed seed should produce the same sequence of output
769
+ /// today, and in the future. PRNGs not able to satisfy this should make
770
+ /// clear notes in their documentation. It is however not required that this
771
+ /// function yield the same state as a reference implementation of the PRNG
772
+ /// given equivalent seed; if necessary another constructor should be used.
744
773
///
745
- /// let seed: &[_] = &[1, 2, 3, 4];
746
- /// let mut rng: StdRng = SeedableRng::from_seed(seed);
747
- /// println!("{}", rng.gen::<f64>());
748
- /// rng.reseed(&[5, 6, 7, 8]);
749
- /// println!("{}", rng.gen::<f64>());
750
- /// ```
751
- fn reseed ( & mut self , Seed ) ;
774
+ /// It may be expected that bits in the seed are well distributed, i.e. that
775
+ /// values like 0, 1 and (size - 1) are unlikely.
776
+ fn from_seed ( seed : Self :: Seed ) -> Self ;
752
777
753
- /// Create a new RNG with the given seed .
778
+ /// Create a new PRNG seeded from another `Rng` .
754
779
///
755
- /// # Example
756
- ///
757
- /// ```rust
758
- /// use rand::{Rng, SeedableRng, StdRng};
759
- ///
760
- /// let seed: &[_] = &[1, 2, 3, 4];
761
- /// let mut rng: StdRng = SeedableRng::from_seed(seed);
762
- /// println!("{}", rng.gen::<f64>());
763
- /// ```
764
- fn from_seed ( seed : Seed ) -> Self ;
780
+ /// Seeding from a cryptographic generator should be fine. On the other
781
+ /// hand, seeding a simple numerical generator from another of the same
782
+ /// type sometimes has serious side effects such as effectively cloning the
783
+ /// generator.
784
+ fn from_rng < R : Rng > ( mut rng : R ) -> Result < Self , Error > {
785
+ let mut seed = Self :: Seed :: default ( ) ;
786
+ let size = mem:: size_of :: < Self :: Seed > ( ) as usize ;
787
+ unsafe {
788
+ let ptr = seed. as_mut ( ) . as_mut_ptr ( ) as * mut u8 ;
789
+ let slice = slice:: from_raw_parts_mut ( ptr, size) ;
790
+ rng. try_fill_bytes ( slice) ?;
791
+ }
792
+ Ok ( Self :: from_seed ( seed) )
793
+ }
765
794
}
766
795
767
796
/// A wrapper for generating floating point numbers uniformly in the
@@ -801,10 +830,11 @@ pub struct Closed01<F>(pub F);
801
830
802
831
/// The standard RNG. This is designed to be efficient on the current
803
832
/// platform.
833
+ ///
834
+ /// The underlying algorithm is not fixed, thus values from this generator
835
+ /// cannot be guaranteed to be reproducible.
804
836
#[ derive( Clone , Debug ) ]
805
- pub struct StdRng {
806
- rng : IsaacWordRng ,
807
- }
837
+ pub struct StdRng ( IsaacWordRng ) ;
808
838
809
839
impl StdRng {
810
840
/// Create a randomly seeded instance of `StdRng`.
@@ -821,10 +851,10 @@ impl StdRng {
821
851
#[ cfg( feature="std" ) ]
822
852
pub fn new ( ) -> Result < StdRng , Error > {
823
853
match OsRng :: new ( ) {
824
- Ok ( mut r) => Ok ( StdRng { rng : r. gen ( ) } ) ,
854
+ Ok ( mut r) => Ok ( StdRng ( r. gen ( ) ) ) ,
825
855
Err ( e1) => {
826
856
match JitterRng :: new ( ) {
827
- Ok ( mut r) => Ok ( StdRng { rng : r. gen ( ) } ) ,
857
+ Ok ( mut r) => Ok ( StdRng ( r. gen ( ) ) ) ,
828
858
Err ( _) => {
829
859
Err ( e1)
830
860
}
@@ -835,36 +865,32 @@ impl StdRng {
835
865
}
836
866
837
867
impl Rng for StdRng {
838
- #[ inline]
839
868
fn next_u32 ( & mut self ) -> u32 {
840
- self . rng . next_u32 ( )
869
+ self . 0 . next_u32 ( )
841
870
}
842
871
843
- #[ inline]
844
872
fn next_u64 ( & mut self ) -> u64 {
845
- self . rng . next_u64 ( )
873
+ self . 0 . next_u64 ( )
846
874
}
847
875
848
- #[ inline]
849
876
fn fill_bytes ( & mut self , dest : & mut [ u8 ] ) {
850
- self . rng . fill_bytes ( dest)
877
+ self . 0 . fill_bytes ( dest) ;
851
878
}
852
-
853
- #[ inline]
879
+
854
880
fn try_fill_bytes ( & mut self , dest : & mut [ u8 ] ) -> Result < ( ) , Error > {
855
- self . rng . try_fill_bytes ( dest)
881
+ self . 0 . try_fill_bytes ( dest)
856
882
}
857
883
}
858
884
859
- impl < ' a > SeedableRng < & ' a [ usize ] > for StdRng {
860
- fn reseed ( & mut self , seed : & ' a [ usize ] ) {
861
- // the internal RNG can just be seeded from the above
862
- // randomness.
863
- self . rng . reseed ( unsafe { mem :: transmute ( seed) } )
885
+ impl SeedableRng for StdRng {
886
+ type Seed = < IsaacWordRng as SeedableRng > :: Seed ;
887
+
888
+ fn from_seed ( seed : Self :: Seed ) -> Self {
889
+ StdRng ( IsaacWordRng :: from_seed ( seed) )
864
890
}
865
891
866
- fn from_seed ( seed : & ' a [ usize ] ) -> StdRng {
867
- StdRng { rng : SeedableRng :: from_seed ( unsafe { mem :: transmute ( seed ) } ) }
892
+ fn from_rng < R : Rng > ( rng : R ) -> Result < Self , Error > {
893
+ IsaacWordRng :: from_rng ( rng ) . map ( |rng| StdRng ( rng ) )
868
894
}
869
895
}
870
896
@@ -1037,7 +1063,7 @@ pub fn sample<T, I, R>(rng: &mut R, iterable: I, amount: usize) -> Vec<T>
1037
1063
mod test {
1038
1064
use impls;
1039
1065
#[ cfg( feature="std" ) ]
1040
- use super :: { random, thread_rng, weak_rng } ;
1066
+ use super :: { random, thread_rng} ;
1041
1067
use super :: { Rng , SeedableRng , StdRng } ;
1042
1068
#[ cfg( feature="alloc" ) ]
1043
1069
use alloc:: boxed:: Box ;
@@ -1057,8 +1083,21 @@ mod test {
1057
1083
}
1058
1084
1059
1085
pub fn rng ( seed : u64 ) -> TestRng < StdRng > {
1060
- let seed = [ seed as usize ] ;
1061
- TestRng { inner : StdRng :: from_seed ( & seed) }
1086
+ // TODO: use from_hashable
1087
+ let mut state = seed;
1088
+ let mut seed = <StdRng as SeedableRng >:: Seed :: default ( ) ;
1089
+ for x in seed. iter_mut ( ) {
1090
+ // PCG algorithm
1091
+ const MUL : u64 = 6364136223846793005 ;
1092
+ const INC : u64 = 11634580027462260723 ;
1093
+ let oldstate = state;
1094
+ state = oldstate. wrapping_mul ( MUL ) . wrapping_add ( INC ) ;
1095
+
1096
+ let xorshifted = ( ( ( oldstate >> 18 ) ^ oldstate) >> 27 ) as u32 ;
1097
+ let rot = ( oldstate >> 59 ) as u32 ;
1098
+ * x = xorshifted. rotate_right ( rot) as u8 ;
1099
+ }
1100
+ TestRng { inner : StdRng :: from_seed ( seed) }
1062
1101
}
1063
1102
1064
1103
struct ConstRng { i : u64 }
@@ -1071,23 +1110,6 @@ mod test {
1071
1110
}
1072
1111
}
1073
1112
1074
- pub fn iter_eq < I , J > ( i : I , j : J ) -> bool
1075
- where I : IntoIterator ,
1076
- J : IntoIterator < Item =I :: Item > ,
1077
- I :: Item : Eq
1078
- {
1079
- // make sure the iterators have equal length
1080
- let mut i = i. into_iter ( ) ;
1081
- let mut j = j. into_iter ( ) ;
1082
- loop {
1083
- match ( i. next ( ) , j. next ( ) ) {
1084
- ( Some ( ref ei) , Some ( ref ej) ) if ei == ej => { }
1085
- ( None , None ) => return true ,
1086
- _ => return false ,
1087
- }
1088
- }
1089
- }
1090
-
1091
1113
#[ test]
1092
1114
fn test_fill_bytes_default ( ) {
1093
1115
let mut r = ConstRng { i : 0x11_22_33_44_55_66_77_88 } ;
@@ -1250,35 +1272,23 @@ mod test {
1250
1272
#[ test]
1251
1273
#[ cfg( target_pointer_width = "32" ) ]
1252
1274
fn test_stdrng_construction ( ) {
1253
- let seed = [ 1 , 23 , 456 , 7890 , 0 , 0 , 0 , 0 ] ;
1254
- let mut rng1 = StdRng :: from_seed ( & seed) ;
1275
+ let seed = [ 1 , 0 , 0 , 0 , 23 , 0 , 0 , 0 , 200 , 1 , 0 , 0 , 210 , 30 , 0 , 0 ,
1276
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ;
1277
+ let mut rng1 = StdRng :: from_seed ( seed) ;
1255
1278
assert_eq ! ( rng1. next_u32( ) , 2869442790 ) ;
1256
1279
1257
- /* FIXME: enable once `from_rng` has landed
1258
1280
let mut rng2 = StdRng :: from_rng ( & mut rng1) . unwrap ( ) ;
1259
- assert_eq!(rng1.next_u32(), 3094074039);
1260
- */
1281
+ assert_eq ! ( rng2. next_u32( ) , 3094074039 ) ;
1261
1282
}
1262
1283
#[ test]
1263
1284
#[ cfg( target_pointer_width = "64" ) ]
1264
1285
fn test_stdrng_construction ( ) {
1265
- let seed = [ 1 , 23 , 456 , 7890 , 0 , 0 , 0 , 0 ] ;
1266
- let mut rng1 = StdRng :: from_seed ( & seed) ;
1267
- assert_eq ! ( rng1. next_u32( ) , 3477963620 ) ;
1286
+ let seed = [ 1 , 0 , 0 , 0 , 23 , 0 , 0 , 0 , 200 , 1 , 0 , 0 , 210 , 30 , 0 , 0 ,
1287
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ;
1288
+ let mut rng1 = StdRng :: from_seed ( seed) ;
1289
+ assert_eq ! ( rng1. next_u64( ) , 14964555543728284049 ) ;
1268
1290
1269
- /* FIXME: enable once `from_rng` has landed
1270
1291
let mut rng2 = StdRng :: from_rng ( & mut rng1) . unwrap ( ) ;
1271
- assert_eq!(rng1.next_u32(), 3094074039);
1272
- */
1273
- }
1274
-
1275
- #[ test]
1276
- #[ cfg( feature="std" ) ]
1277
- fn test_weak_rng ( ) {
1278
- let s = weak_rng ( ) . gen_iter :: < usize > ( ) . take ( 256 ) . collect :: < Vec < usize > > ( ) ;
1279
- let mut ra: StdRng = SeedableRng :: from_seed ( & s[ ..] ) ;
1280
- let mut rb: StdRng = SeedableRng :: from_seed ( & s[ ..] ) ;
1281
- assert ! ( iter_eq( ra. gen_ascii_chars( ) . take( 100 ) ,
1282
- rb. gen_ascii_chars( ) . take( 100 ) ) ) ;
1292
+ assert_eq ! ( rng2. next_u64( ) , 919595328260451758 ) ;
1283
1293
}
1284
1294
}
0 commit comments