@@ -254,6 +254,7 @@ use std::mem;
254
254
use std:: io;
255
255
use std:: rc:: Rc ;
256
256
use std:: num:: Wrapping as w;
257
+ use std:: time;
257
258
258
259
pub use os:: OsRng ;
259
260
@@ -891,13 +892,9 @@ impl<'a> SeedableRng<&'a [usize]> for StdRng {
891
892
/// seeded `Rng` for consistency over time you should pick one algorithm and
892
893
/// create the `Rng` yourself.
893
894
///
894
- /// This will read randomness from the operating system to seed the
895
- /// generator.
895
+ /// This will seed the generator with randomness from thread_rng.
896
896
pub fn weak_rng ( ) -> XorShiftRng {
897
- match OsRng :: new ( ) {
898
- Ok ( mut r) => r. gen ( ) ,
899
- Err ( e) => panic ! ( "weak_rng: failed to create seeded RNG: {:?}" , e)
900
- }
897
+ thread_rng ( ) . gen ( )
901
898
}
902
899
903
900
/// Controls how the thread-local RNG is reseeded.
@@ -906,9 +903,9 @@ struct ThreadRngReseeder;
906
903
907
904
impl reseeding:: Reseeder < StdRng > for ThreadRngReseeder {
908
905
fn reseed ( & mut self , rng : & mut StdRng ) {
909
- * rng = match StdRng :: new ( ) {
910
- Ok ( r) => r,
911
- Err ( e ) => panic ! ( "could not reseed thread_rng: {}" , e )
906
+ match StdRng :: new ( ) {
907
+ Ok ( r) => * rng = r,
908
+ Err ( _ ) => rng . reseed ( & weak_seed ( ) )
912
909
}
913
910
}
914
911
}
@@ -925,8 +922,9 @@ pub struct ThreadRng {
925
922
/// generator, seeded by the system. Intended to be used in method
926
923
/// chaining style, e.g. `thread_rng().gen::<i32>()`.
927
924
///
928
- /// The RNG provided will reseed itself from the operating system
929
- /// after generating a certain amount of randomness.
925
+ /// After generating a certain amount of randomness, the RNG will reseed itself
926
+ /// from the operating system or, if the operating system RNG returns an error,
927
+ /// a seed based on the current system time.
930
928
///
931
929
/// The internal RNG used is platform and architecture dependent, even
932
930
/// if the operating system random number generator is rigged to give
@@ -937,7 +935,7 @@ pub fn thread_rng() -> ThreadRng {
937
935
thread_local ! ( static THREAD_RNG_KEY : Rc <RefCell <ThreadRngInner >> = {
938
936
let r = match StdRng :: new( ) {
939
937
Ok ( r) => r,
940
- Err ( e ) => panic! ( "could not initialize thread_rng: {}" , e )
938
+ Err ( _ ) => StdRng :: from_seed ( & weak_seed ( ) )
941
939
} ;
942
940
let rng = reseeding:: ReseedingRng :: new( r,
943
941
THREAD_RNG_RESEED_THRESHOLD ,
@@ -948,6 +946,14 @@ pub fn thread_rng() -> ThreadRng {
948
946
ThreadRng { rng : THREAD_RNG_KEY . with ( |t| t. clone ( ) ) }
949
947
}
950
948
949
+ fn weak_seed ( ) -> [ usize ; 2 ] {
950
+ let now = time:: SystemTime :: now ( ) ;
951
+ let unix_time = now. duration_since ( time:: UNIX_EPOCH ) . unwrap ( ) ;
952
+ let seconds = unix_time. as_secs ( ) as usize ;
953
+ let nanoseconds = unix_time. subsec_nanos ( ) as usize ;
954
+ [ seconds, nanoseconds]
955
+ }
956
+
951
957
impl Rng for ThreadRng {
952
958
fn next_u32 ( & mut self ) -> u32 {
953
959
self . rng . borrow_mut ( ) . next_u32 ( )
@@ -1042,7 +1048,8 @@ pub fn sample<T, I, R>(rng: &mut R, iterable: I, amount: usize) -> Vec<T>
1042
1048
1043
1049
#[ cfg( test) ]
1044
1050
mod test {
1045
- use super :: { Rng , thread_rng, random, SeedableRng , StdRng , sample} ;
1051
+ use super :: { Rng , thread_rng, random, SeedableRng , StdRng , sample,
1052
+ weak_rng} ;
1046
1053
use std:: iter:: repeat;
1047
1054
1048
1055
pub struct MyRng < R > { inner : R }
@@ -1286,4 +1293,13 @@ mod test {
1286
1293
let string2 = r. gen_ascii_chars ( ) . take ( 100 ) . collect :: < String > ( ) ;
1287
1294
assert_eq ! ( string1, string2) ;
1288
1295
}
1296
+
1297
+ #[ test]
1298
+ fn test_weak_rng ( ) {
1299
+ let s = weak_rng ( ) . gen_iter :: < usize > ( ) . take ( 256 ) . collect :: < Vec < usize > > ( ) ;
1300
+ let mut ra: StdRng = SeedableRng :: from_seed ( & s[ ..] ) ;
1301
+ let mut rb: StdRng = SeedableRng :: from_seed ( & s[ ..] ) ;
1302
+ assert ! ( iter_eq( ra. gen_ascii_chars( ) . take( 100 ) ,
1303
+ rb. gen_ascii_chars( ) . take( 100 ) ) ) ;
1304
+ }
1289
1305
}
0 commit comments