@@ -254,18 +254,25 @@ pub use os::OsRng;
254
254
255
255
pub use isaac:: { IsaacRng , Isaac64Rng } ;
256
256
pub use chacha:: ChaChaRng ;
257
+ pub use xorshift:: { XorShift64Rng , XorShift128PRng } ;
257
258
258
259
#[ cfg( target_pointer_width = "32" ) ]
259
260
use IsaacRng as IsaacWordRng ;
260
261
#[ cfg( target_pointer_width = "64" ) ]
261
262
use Isaac64Rng as IsaacWordRng ;
262
263
264
+ #[ cfg( target_pointer_width = "32" ) ]
265
+ use XorShift64Rng as InnerWeakRng ;
266
+ #[ cfg( target_pointer_width = "64" ) ]
267
+ use XorShift128PRng as InnerWeakRng ;
268
+
263
269
use distributions:: { Range , IndependentSample } ;
264
270
use distributions:: range:: SampleRange ;
265
271
266
272
pub mod distributions;
267
273
pub mod isaac;
268
274
pub mod chacha;
275
+ pub mod xorshift;
269
276
pub mod reseeding;
270
277
mod rand_impls;
271
278
pub mod os;
@@ -598,93 +605,6 @@ pub trait SeedableRng<Seed>: Rng {
598
605
fn from_seed ( seed : Seed ) -> Self ;
599
606
}
600
607
601
- /// An Xorshift[1] random number
602
- /// generator.
603
- ///
604
- /// The Xorshift algorithm is not suitable for cryptographic purposes
605
- /// but is very fast. If you do not know for sure that it fits your
606
- /// requirements, use a more secure one such as `IsaacRng` or `OsRng`.
607
- ///
608
- /// [1]: Marsaglia, George (July 2003). ["Xorshift
609
- /// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
610
- /// Statistical Software*. Vol. 8 (Issue 14).
611
- #[ allow( missing_copy_implementations) ]
612
- #[ derive( Clone ) ]
613
- pub struct XorShiftRng {
614
- x : w32 ,
615
- y : w32 ,
616
- z : w32 ,
617
- w : w32 ,
618
- }
619
-
620
- impl XorShiftRng {
621
- /// Creates a new XorShiftRng instance which is not seeded.
622
- ///
623
- /// The initial values of this RNG are constants, so all generators created
624
- /// by this function will yield the same stream of random numbers. It is
625
- /// highly recommended that this is created through `SeedableRng` instead of
626
- /// this function
627
- pub fn new_unseeded ( ) -> XorShiftRng {
628
- XorShiftRng {
629
- x : w ( 0x193a6754 ) ,
630
- y : w ( 0xa8a7d469 ) ,
631
- z : w ( 0x97830e05 ) ,
632
- w : w ( 0x113ba7bb ) ,
633
- }
634
- }
635
- }
636
-
637
- impl Rng for XorShiftRng {
638
- #[ inline]
639
- fn next_u32 ( & mut self ) -> u32 {
640
- let x = self . x ;
641
- let t = x ^ ( x << 11 ) ;
642
- self . x = self . y ;
643
- self . y = self . z ;
644
- self . z = self . w ;
645
- let w_ = self . w ;
646
- self . w = w_ ^ ( w_ >> 19 ) ^ ( t ^ ( t >> 8 ) ) ;
647
- self . w . 0
648
- }
649
- }
650
-
651
- impl SeedableRng < [ u32 ; 4 ] > for XorShiftRng {
652
- /// Reseed an XorShiftRng. This will panic if `seed` is entirely 0.
653
- fn reseed ( & mut self , seed : [ u32 ; 4 ] ) {
654
- assert ! ( !seed. iter( ) . all( |& x| x == 0 ) ,
655
- "XorShiftRng.reseed called with an all zero seed." ) ;
656
-
657
- self . x = w ( seed[ 0 ] ) ;
658
- self . y = w ( seed[ 1 ] ) ;
659
- self . z = w ( seed[ 2 ] ) ;
660
- self . w = w ( seed[ 3 ] ) ;
661
- }
662
-
663
- /// Create a new XorShiftRng. This will panic if `seed` is entirely 0.
664
- fn from_seed ( seed : [ u32 ; 4 ] ) -> XorShiftRng {
665
- assert ! ( !seed. iter( ) . all( |& x| x == 0 ) ,
666
- "XorShiftRng::from_seed called with an all zero seed." ) ;
667
-
668
- XorShiftRng {
669
- x : w ( seed[ 0 ] ) ,
670
- y : w ( seed[ 1 ] ) ,
671
- z : w ( seed[ 2 ] ) ,
672
- w : w ( seed[ 3 ] ) ,
673
- }
674
- }
675
- }
676
-
677
- impl Rand for XorShiftRng {
678
- fn rand < R : Rng > ( rng : & mut R ) -> XorShiftRng {
679
- let mut tuple: ( u32 , u32 , u32 , u32 ) = rng. gen ( ) ;
680
- while tuple == ( 0 , 0 , 0 , 0 ) {
681
- tuple = rng. gen ( ) ;
682
- }
683
- let ( x, y, z, w_) = tuple;
684
- XorShiftRng { x : w ( x) , y : w ( y) , z : w ( z) , w : w ( w_) }
685
- }
686
- }
687
-
688
608
/// A wrapper for generating floating point numbers uniformly in the
689
609
/// open interval `(0,1)` (not including either endpoint).
690
610
///
@@ -766,6 +686,25 @@ impl<'a> SeedableRng<&'a [usize]> for StdRng {
766
686
}
767
687
}
768
688
689
+ /// The standard RNG. This is designed to be efficient on the current
690
+ /// platform.
691
+ #[ derive( Copy , Clone ) ]
692
+ pub struct WeakRng {
693
+ rng : InnerWeakRng ,
694
+ }
695
+
696
+ impl Rng for WeakRng {
697
+ #[ inline]
698
+ fn next_u32 ( & mut self ) -> u32 {
699
+ self . rng . next_u32 ( )
700
+ }
701
+
702
+ #[ inline]
703
+ fn next_u64 ( & mut self ) -> u64 {
704
+ self . rng . next_u64 ( )
705
+ }
706
+ }
707
+
769
708
/// Create a weak random number generator with a default algorithm and seed.
770
709
///
771
710
/// It returns the fastest `Rng` algorithm currently available in Rust without
@@ -775,9 +714,9 @@ impl<'a> SeedableRng<&'a [usize]> for StdRng {
775
714
///
776
715
/// This will read randomness from the operating system to seed the
777
716
/// generator.
778
- pub fn weak_rng ( ) -> XorShiftRng {
717
+ pub fn weak_rng ( ) -> WeakRng {
779
718
match OsRng :: new ( ) {
780
- Ok ( mut r ) => r . gen ( ) ,
719
+ Ok ( mut os_rnd ) => WeakRng { rng : os_rnd . gen ( ) } ,
781
720
Err ( e) => panic ! ( "weak_rng: failed to create seeded RNG: {:?}" , e)
782
721
}
783
722
}
0 commit comments