diff --git a/.lock b/.lock new file mode 100644 index 000000000..e69de29bb diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/crates.js b/crates.js new file mode 100644 index 000000000..013cf0e38 --- /dev/null +++ b/crates.js @@ -0,0 +1,2 @@ +window.ALL_CRATES = ["rand_core","rand_mt"]; +//{"start":21,"fragment_lengths":[11,10]} \ No newline at end of file diff --git a/help.html b/help.html new file mode 100644 index 000000000..48e5cd1fa --- /dev/null +++ b/help.html @@ -0,0 +1 @@ +
The BlockRngCore
trait and implementation helpers
The BlockRngCore
trait exists to assist in the implementation of RNGs
+which generate a block of data in a cache instead of returning generated
+values directly.
Usage of this trait is optional, but provides two advantages:
+implementations only need to concern themselves with generation of the
+block, not the various RngCore
methods (especially fill_bytes
, where
+the optimal implementations are not trivial), and this allows
+ReseedingRng
(see rand
crate) perform periodic
+reseeding with very low overhead.
use rand_core::{RngCore, SeedableRng};
+use rand_core::block::{BlockRngCore, BlockRng};
+
+struct MyRngCore;
+
+impl BlockRngCore for MyRngCore {
+ type Item = u32;
+ type Results = [u32; 16];
+
+ fn generate(&mut self, results: &mut Self::Results) {
+ unimplemented!()
+ }
+}
+
+impl SeedableRng for MyRngCore {
+ type Seed = [u8; 32];
+ fn from_seed(seed: Self::Seed) -> Self {
+ unimplemented!()
+ }
+}
+
+// optionally, also implement CryptoRng for MyRngCore
+
+// Final RNG.
+let mut rng = BlockRng::<MyRngCore>::seed_from_u64(0);
+println!("First value: {}", rng.next_u32());
RngCore
for some type implementing
+BlockRngCore
with u32
array buffer; i.e. this can be used to implement
+a full RNG from just a generate
function.RngCore
for some type implementing
+BlockRngCore
with u64
array buffer; i.e. this can be used to implement
+a full RNG from just a generate
function.[u32; N]
). This technique is commonly used by
+cryptographic RNGs to improve performance.pub struct BlockRng<R: BlockRngCore + ?Sized> {
+ pub core: R,
+ /* private fields */
+}
A wrapper type implementing RngCore
for some type implementing
+BlockRngCore
with u32
array buffer; i.e. this can be used to implement
+a full RNG from just a generate
function.
The core
field may be accessed directly but the results buffer may not.
+PRNG implementations can simply use a type alias
+(pub type MyRng = BlockRng<MyRngCore>;
) but might prefer to use a
+wrapper type (pub struct MyRng(BlockRng<MyRngCore>);
); the latter must
+re-implement RngCore
but hides the implementation details and allows
+extra functionality to be defined on the RNG
+(e.g. impl MyRng { fn set_stream(...){...} }
).
BlockRng
has heavily optimized implementations of the RngCore
methods
+reading values from the results buffer, as well as
+calling BlockRngCore::generate
directly on the output array when
+fill_bytes
/ try_fill_bytes
is called on a large array. These methods
+also handle the bookkeeping of when to generate a new batch of values.
No whole generated u32
values are thrown away and all values are consumed
+in-order. next_u32
simply takes the next available u32
value.
+next_u64
is implemented by combining two u32
values, least
+significant first. fill_bytes
and try_fill_bytes
consume a whole
+number of u32
values, converting each u32
to a byte slice in
+little-endian order. If the requested byte length is not a multiple of 4,
+some bytes will be discarded.
See also BlockRng64
which uses u64
array buffers. Currently there is
+no direct support for other buffer types.
For easy initialization BlockRng
also implements SeedableRng
.
core: R
The core part of the RNG, implementing the generate
function.
Create a new BlockRng
from an existing RNG implementing
+BlockRngCore
. Results will be generated on first use.
Get the index into the result buffer.
+If this is equal to or larger than the size of the result buffer then
+the buffer is “empty” and generate()
must be called to produce new
+results.
Reset the number of available results. +This will force a new set of results to be generated on next use.
+Generate a new set of results immediately, setting the index to the +given value.
+dest
with random data. Read moreclone_to_uninit
)RngCore
trait object.pub struct BlockRng64<R: BlockRngCore + ?Sized> {
+ pub core: R,
+ /* private fields */
+}
A wrapper type implementing RngCore
for some type implementing
+BlockRngCore
with u64
array buffer; i.e. this can be used to implement
+a full RNG from just a generate
function.
This is similar to BlockRng
, but specialized for algorithms that operate
+on u64
values.
No whole generated u64
values are thrown away and all values are consumed
+in-order. next_u64
simply takes the next available u64
value.
+next_u32
is however a bit special: half of a u64
is consumed, leaving
+the other half in the buffer. If the next function called is next_u32
+then the other half is then consumed, however both next_u64
and
+fill_bytes
discard the rest of any half-consumed u64
s when called.
fill_bytes
and try_fill_bytes
consume a whole number of u64
+values. If the requested length is not a multiple of 8, some bytes will be
+discarded.
core: R
The core part of the RNG, implementing the generate
function.
Create a new BlockRng
from an existing RNG implementing
+BlockRngCore
. Results will be generated on first use.
Get the index into the result buffer.
+If this is equal to or larger than the size of the result buffer then
+the buffer is “empty” and generate()
must be called to produce new
+results.
Reset the number of available results. +This will force a new set of results to be generated on next use.
+Generate a new set of results immediately, setting the index to the +given value.
+source
. Read moredest
with random data. Read moreclone_to_uninit
)pub trait BlockRngCore {
+ type Item;
+ type Results: AsRef<[Self::Item]> + AsMut<[Self::Item]> + Default;
+
+ // Required method
+ fn generate(&mut self, results: &mut Self::Results);
+}
A trait for RNGs which do not generate random numbers individually, but in
+blocks (typically [u32; N]
). This technique is commonly used by
+cryptographic RNGs to improve performance.
See the module documentation for details.
+Redirecting to ../../rand_core/struct.Error.html...
+ + + \ No newline at end of file diff --git a/rand_core/impls/fn.fill_bytes_via_next.html b/rand_core/impls/fn.fill_bytes_via_next.html new file mode 100644 index 000000000..9c4411f27 --- /dev/null +++ b/rand_core/impls/fn.fill_bytes_via_next.html @@ -0,0 +1,6 @@ +pub fn fill_bytes_via_next<R: RngCore + ?Sized>(rng: &mut R, dest: &mut [u8])
Implement fill_bytes
via next_u64
and next_u32
, little-endian order.
The fastest way to fill a slice is usually to work as long as possible with
+integers. That is why this method mostly uses next_u64
, and only when
+there are 4 or less bytes remaining at the end of the slice it uses
+next_u32
once.
pub fn fill_via_u32_chunks(src: &[u32], dest: &mut [u8]) -> (usize, usize)
Implement fill_bytes
by reading chunks from the output buffer of a block
+based RNG.
The return values are (consumed_u32, filled_u8)
.
filled_u8
is the number of filled bytes in dest
, which may be less than
+the length of dest
.
+consumed_u32
is the number of words consumed from src
, which is the same
+as filled_u8 / 4
rounded up.
(from IsaacRng
)
fn fill_bytes(&mut self, dest: &mut [u8]) {
+ let mut read_len = 0;
+ while read_len < dest.len() {
+ if self.index >= self.rsl.len() {
+ self.isaac();
+ }
+
+ let (consumed_u32, filled_u8) =
+ impls::fill_via_u32_chunks(&mut self.rsl[self.index..],
+ &mut dest[read_len..]);
+
+ self.index += consumed_u32;
+ read_len += filled_u8;
+ }
+}
pub fn fill_via_u64_chunks(src: &[u64], dest: &mut [u8]) -> (usize, usize)
Implement fill_bytes
by reading chunks from the output buffer of a block
+based RNG.
The return values are (consumed_u64, filled_u8)
.
+filled_u8
is the number of filled bytes in dest
, which may be less than
+the length of dest
.
+consumed_u64
is the number of words consumed from src
, which is the same
+as filled_u8 / 8
rounded up.
See fill_via_u32_chunks
for an example.
Helper functions for implementing RngCore
functions.
For cross-platform reproducibility, these functions all use Little Endian:
+least-significant part first. For example, next_u64_via_u32
takes u32
+values x, y
, then outputs (y << 32) | x
. To implement next_u32
+from next_u64
in little-endian order, one should use next_u64() as u32
.
Byte-swapping (like the std to_le
functions) is only needed to convert
+to/from byte sequences, and since its purpose is reproducibility,
+non-reproducible sources (e.g. OsRng
) need not bother with it.
fill_bytes
via next_u64
and next_u32
, little-endian order.fill_bytes
by reading chunks from the output buffer of a block
+based RNG.fill_bytes
by reading chunks from the output buffer of a block
+based RNG.next_u32
via fill_bytes
, little-endian order.next_u64
via fill_bytes
, little-endian order.next_u64
via next_u32
, little-endian order.Random number generation traits
+This crate is mainly of interest to crates publishing implementations of
+RngCore
. Other users are encouraged to use the rand
crate instead
+which re-exports the main traits and error types.
RngCore
is the core trait implemented by algorithmic pseudo-random number
+generators and external random-number sources.
SeedableRng
is an extension trait for construction from fixed seeds and
+other random number generators.
Error
is provided for error-handling. It is safe to use in no_std
+environments.
The impls
and le
sub-modules include a few small functions to assist
+implementation of RngCore
.
BlockRngCore
trait and implementation helpersRngCore
functions.RngCore
or BlockRngCore
+implementation is supposed to be cryptographically secure.Little-Endian utilities
+Little-Endian order has been chosen for internal usage; this makes some +useful functions available.
+src
into dst
.src
into dst
.pub struct Error { /* private fields */ }
Error type of random number generators
+In order to be compatible with std
and no_std
, this type has two
+possible implementations: with std
a boxed Error
trait object is stored,
+while with no_std
we merely store an error code.
Codes at or above this point can be used by users to define their own +custom errors.
+This has a fixed value of (1 << 31) + (1 << 30) = 0xC000_0000
,
+therefore the number of values available for custom codes is 1 << 30
.
This is identical to getrandom::Error::CUSTOM_START
.
Codes below this point represent OS Errors (i.e. positive i32 values).
+Codes at or above this point, but below Error::CUSTOM_START
are
+reserved for use by the rand
and getrandom
crates.
This is identical to getrandom::Error::INTERNAL_START
.
Extract the raw OS error code (if this error came from the OS)
+This method is identical to std::io::Error::raw_os_error()
, except
+that it works in no_std
contexts. If this method returns None
, the
+error value can still be formatted via the Display
implementation.
Retrieve the error code, if any.
+If this Error
was constructed via From<NonZeroU32>
, then this method
+will return this NonZeroU32
code (for no_std
this is always the
+case). Otherwise, this method will return None
.
pub trait CryptoRng { }
A marker trait used to indicate that an RngCore
or BlockRngCore
+implementation is supposed to be cryptographically secure.
Cryptographically secure generators, also known as CSPRNGs, should +satisfy an additional properties over other generators: given the first +k bits of an algorithm’s output +sequence, it should not be possible using polynomial-time algorithms to +predict the next bit with probability significantly greater than 50%.
+Some generators may satisfy an additional property, however this is not +required by this trait: if the CSPRNG’s state is revealed, it should not be +computationally-feasible to reconstruct output prior to this. Some other +generators allow backwards-computation and are considered reversible.
+Note that this trait is provided for guidance only and cannot guarantee +suitability for cryptographic applications. In general it should only be +implemented for well-reviewed code implementing well-regarded algorithms.
+Note also that use of a CryptoRng
does not protect against other
+weaknesses such as seeding from a weak entropy source or leaking state.
pub trait CryptoRngCore: CryptoRng + RngCore {
+ // Required method
+ fn as_rngcore(&mut self) -> &mut dyn RngCore;
+}
An extension trait that is automatically implemented for any type
+implementing RngCore
and CryptoRng
.
It may be used as a trait object, and supports upcasting to RngCore
via
+the CryptoRngCore::as_rngcore
method.
use rand_core::CryptoRngCore;
+
+#[allow(unused)]
+fn make_token(rng: &mut dyn CryptoRngCore) -> [u8; 32] {
+ let mut buf = [0u8; 32];
+ rng.fill_bytes(&mut buf);
+ buf
+}
Upcast to an RngCore
trait object.
pub trait RngCore {
+ // Required methods
+ fn next_u32(&mut self) -> u32;
+ fn next_u64(&mut self) -> u64;
+ fn fill_bytes(&mut self, dest: &mut [u8]);
+ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>;
+}
The core of a random number generator.
+This trait encapsulates the low-level functionality common to all
+generators, and is the “back end”, to be implemented by generators.
+End users should normally use the Rng
trait from the rand
crate,
+which is automatically implemented for every type implementing RngCore
.
Three different methods for generating random data are provided since the
+optimal implementation of each is dependent on the type of generator. There
+is no required relationship between the output of each; e.g. many
+implementations of fill_bytes
consume a whole number of u32
or u64
+values and drop any remaining unused bytes. The same can happen with the
+next_u32
and next_u64
methods, implementations may discard some
+random bits for efficiency.
The try_fill_bytes
method is a variant of fill_bytes
allowing error
+handling; it is not deemed sufficiently useful to add equivalents for
+next_u32
or next_u64
since the latter methods are almost always used
+with algorithmic generators (PRNGs), which are normally infallible.
Implementers should produce bits uniformly. Pathological RNGs (e.g. always
+returning the same value, or never setting certain bits) can break rejection
+sampling used by random distributions, and also break other RNGs when
+seeding them via SeedableRng::from_rng
.
Algorithmic generators implementing SeedableRng
should normally have
+portable, reproducible output, i.e. fix Endianness when converting values
+to avoid platform differences, and avoid making any changes which affect
+output (except by communicating that the release has breaking changes).
Typically an RNG will implement only one of the methods available
+in this trait directly, then use the helper functions from the
+impls
module to implement the other methods.
It is recommended that implementations also implement:
+Debug
with a custom implementation which does not print any internal
+state (at least, CryptoRng
s should not risk leaking state through
+Debug
).Serialize
and Deserialize
(from Serde), preferably making Serde
+support optional at the crate level in PRNG libs.Clone
, if possible.Copy
(accidental copies may cause repeated values).Default
for pseudorandom generators, but instead
+implement SeedableRng
, to guide users towards proper seeding.
+External / hardware RNGs can choose to implement Default
.Eq
and PartialEq
could be implemented, but are probably not useful.A simple example, obviously not generating very random output:
+ +#![allow(dead_code)]
+use rand_core::{RngCore, Error, impls};
+
+struct CountingRng(u64);
+
+impl RngCore for CountingRng {
+ fn next_u32(&mut self) -> u32 {
+ self.next_u64() as u32
+ }
+
+ fn next_u64(&mut self) -> u64 {
+ self.0 += 1;
+ self.0
+ }
+
+ fn fill_bytes(&mut self, dest: &mut [u8]) {
+ impls::fill_bytes_via_next(self, dest)
+ }
+
+ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+ Ok(self.fill_bytes(dest))
+ }
+}
Return the next random u32
.
RNGs must implement at least one method from this trait directly. In
+the case this method is not implemented directly, it can be implemented
+using self.next_u64() as u32
or via impls::next_u32_via_fill
.
Return the next random u64
.
RNGs must implement at least one method from this trait directly. In
+the case this method is not implemented directly, it can be implemented
+via impls::next_u64_via_u32
or via impls::next_u64_via_fill
.
Fill dest
with random data.
RNGs must implement at least one method from this trait directly. In
+the case this method is not implemented directly, it can be implemented
+via impls::fill_bytes_via_next
or
+via RngCore::try_fill_bytes
; if this generator can
+fail the implementation must choose how best to handle errors here
+(e.g. panic with a descriptive message or log a warning and retry a few
+times).
This method should guarantee that dest
is entirely filled
+with new data, and may panic if this is impossible
+(e.g. reading past the end of a file that is being used as the
+source of randomness).
Fill dest
entirely with random data.
This is the only method which allows an RNG to report errors while
+generating random data thus making this the primary method implemented
+by external (true) RNGs (e.g. OsRng
) which can fail. It may be used
+directly to generate keys and to seed (infallible) PRNGs.
Other than error handling, this method is identical to RngCore::fill_bytes
;
+thus this may be implemented using Ok(self.fill_bytes(dest))
or
+fill_bytes
may be implemented with
+self.try_fill_bytes(dest).unwrap()
or more specific error handling.
pub trait SeedableRng: Sized {
+ type Seed: Sized + Default + AsMut<[u8]>;
+
+ // Required method
+ fn from_seed(seed: Self::Seed) -> Self;
+
+ // Provided methods
+ fn seed_from_u64(state: u64) -> Self { ... }
+ fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> { ... }
+}
A random number generator that can be explicitly seeded.
+This trait encapsulates the low-level functionality common to all +pseudo-random number generators (PRNGs, or algorithmic generators).
+Seed type, which is restricted to types mutably-dereferenceable as u8
+arrays (we recommend [u8; N]
for some N
).
It is recommended to seed PRNGs with a seed of at least circa 100 bits,
+which means an array of [u8; 12]
or greater to avoid picking RNGs with
+partially overlapping periods.
For cryptographic RNG’s a seed of 256 bits is recommended, [u8; 32]
.
SeedableRng
for RNGs with large seedsNote that the required traits core::default::Default
and
+core::convert::AsMut<u8>
are not implemented for large arrays
+[u8; N]
with N
> 32. To be able to implement the traits required by
+SeedableRng
for RNGs with such large seeds, the newtype pattern can be
+used:
use rand_core::SeedableRng;
+
+const N: usize = 64;
+pub struct MyRngSeed(pub [u8; N]);
+pub struct MyRng(MyRngSeed);
+
+impl Default for MyRngSeed {
+ fn default() -> MyRngSeed {
+ MyRngSeed([0; N])
+ }
+}
+
+impl AsMut<[u8]> for MyRngSeed {
+ fn as_mut(&mut self) -> &mut [u8] {
+ &mut self.0
+ }
+}
+
+impl SeedableRng for MyRng {
+ type Seed = MyRngSeed;
+
+ fn from_seed(seed: MyRngSeed) -> MyRng {
+ MyRng(seed)
+ }
+}
Create a new PRNG using the given seed.
+PRNG implementations are allowed to assume that bits in the seed are
+well distributed. That means usually that the number of one and zero
+bits are roughly equal, and values like 0, 1 and (size - 1) are unlikely.
+Note that many non-cryptographic PRNGs will show poor quality output
+if this is not adhered to. If you wish to seed from simple numbers, use
+seed_from_u64
instead.
All PRNG implementations should be reproducible unless otherwise noted:
+given a fixed seed
, the same sequence of output should be produced
+on all runs, library versions and architectures (e.g. check endianness).
+Any “value-breaking” changes to the generator should require bumping at
+least the minor version and documentation of the change.
It is not required that this function yield the same state as a +reference implementation of the PRNG given equivalent seed; if necessary +another constructor replicating behaviour from a reference +implementation can be added.
+PRNG implementations should make sure from_seed
never panics. In the
+case that some special values (like an all zero seed) are not viable
+seeds it is preferable to map these to alternative constant value(s),
+for example 0xBAD5EEDu32
or 0x0DDB1A5E5BAD5EEDu64
(“odd biases? bad
+seed”). This is assuming only a small number of values must be rejected.
Create a new PRNG using a u64
seed.
This is a convenience-wrapper around from_seed
to allow construction
+of any SeedableRng
from a simple u64
value. It is designed such that
+low Hamming Weight numbers like 0 and 1 can be used and should still
+result in good, independent seeds to the PRNG which is returned.
This is not suitable for cryptography, as should be clear given that +the input size is only 64 bits.
+Implementations for PRNGs may provide their own implementations of +this function, but the default implementation should be good enough for +all purposes. Changing the implementation of this function should be +considered a value-breaking change.
+Create a new PRNG seeded from another Rng
.
This may be useful when needing to rapidly seed many PRNGs from a master +PRNG, and to allow forking of PRNGs. It may be considered deterministic.
+The master PRNG should be at least as high quality as the child PRNGs.
+When seeding non-cryptographic child PRNGs, we recommend using a
+different algorithm for the master PRNG (ideally a CSPRNG) to avoid
+correlations between the child PRNGs. If this is not possible (e.g.
+forking using small non-crypto PRNGs) ensure that your PRNG has a good
+mixing function on the output or consider use of a hash function with
+from_seed
.
Note that seeding XorShiftRng
from another XorShiftRng
provides an
+extreme example of what can go wrong: the new PRNG will be a clone
+of the parent.
PRNG implementations are allowed to assume that a good RNG is provided
+for seeding, and that it is cryptographically secure when appropriate.
+As of rand
0.7 / rand_core
0.5, implementations overriding this
+method should ensure the implementation satisfies reproducibility
+(in prior versions this was not required).
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
#[non_exhaustive]pub enum RecoverRngError {
+ TooFewSamples(usize),
+ TooManySamples(usize),
+}
Error returned from fallible Mersenne Twister recovery constructors.
+When the std
feature is enabled, this type implements std::error::Error
.
Attempted to recover an RNG with too many samples.
+Recover constructors require an exact number of samples to ensure the +recovered RNG matches the state of the RNG that supplied all of the +samples.
+Attempted to recover an RNG with too few samples.
+Too few samples leaves the internal state buffer partially +uninitialized.
+Recover constructors require an exact number of samples to ensure the +recovered RNG matches the state of the RNG that supplied all of the +samples.
+source
. Read moreclone_to_uninit
)Mersenne Twister random number generators.
+This is a native Rust implementation of a selection of Mersenne Twister +generators. Mersenne Twister is not suitable for cryptographic use.
+This crate provides:
+Mt19937GenRand32
, the original reference Mersenne Twister
+implementation known as MT19937
. This is a good choice on both 32-bit
+and 64-bit CPUs (for 32-bit output).Mt19937GenRand64
, the 64-bit variant of MT19937
known as
+MT19937-64
. This algorithm produces a different output stream than
+MT19937
and produces 64-bit output. This is a good choice on 64-bit
+CPUs.Both of these RNGs use approximately 2.5 kilobytes of state.
+Mt19937GenRand32
uses a 32-bit seed. Mt19937GenRand64
uses a 64-bit
+seed. Both can be seeded from an iterator of seeds.
Both RNGs implement a recover
constructor which can reconstruct the RNG
+state from a sequence of output samples.
You can seed a RNG and begin sampling it:
+ +// Create the RNG.
+let mut rng = Mt64::new(0x1234_567_89ab_cdef_u64);
+// start grabbing randomness from rng...
+let mut buf = vec![0; 512];
+rng.fill_bytes(&mut buf);
Or if you want to use the default (fixed) seeds that are specified in the +reference implementations:
+ +let default = Mt::default();
+let mt = Mt::new_unseeded();
+assert_eq!(default, mt);
rand_mt
is no_std
compatible. rand_mt
has several optional features
+that are enabled by default:
rand_core
. Activating this
+feature implements RngCore
and SeedableRng
on the RNGs in this crate.std::error::Error
impls on error types in this
+crate.Mersenne Twister requires approximately 2.5 kilobytes of internal state. To
+make the RNGs implemented in this crate practical to embed in other structs,
+you may wish to store the RNG in a Box
.
Mt19937GenRand32
, 32-bit Mersenne Twister.Mt19937GenRand64
, 64-bit Mersenne Twister.Redirecting to ../../rand_mt/struct.Mt19937GenRand32.html...
+ + + \ No newline at end of file diff --git a/rand_mt/mt64/struct.Mt19937GenRand64.html b/rand_mt/mt64/struct.Mt19937GenRand64.html new file mode 100644 index 000000000..53dd4eb5a --- /dev/null +++ b/rand_mt/mt64/struct.Mt19937GenRand64.html @@ -0,0 +1,11 @@ + + + + +Redirecting to ../../rand_mt/struct.Mt19937GenRand64.html...
+ + + \ No newline at end of file diff --git a/rand_mt/sidebar-items.js b/rand_mt/sidebar-items.js new file mode 100644 index 000000000..407f0bd34 --- /dev/null +++ b/rand_mt/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["RecoverRngError"],"struct":["Mt19937GenRand32","Mt19937GenRand64"],"type":["Mt","Mt64"]}; \ No newline at end of file diff --git a/rand_mt/struct.Mt19937GenRand32.html b/rand_mt/struct.Mt19937GenRand32.html new file mode 100644 index 000000000..94fd525af --- /dev/null +++ b/rand_mt/struct.Mt19937GenRand32.html @@ -0,0 +1,221 @@ +pub struct Mt19937GenRand32 { /* private fields */ }
The 32-bit flavor of the Mersenne Twister pseudorandom number +generator.
+The official name of this RNG is MT19937
. It natively outputs u32
.
Mt19937GenRand32
requires approximately 2.5 kilobytes of internal state.
You may wish to store an Mt19937GenRand32
on the heap in a Box
to make
+it easier to embed in another struct.
Mt19937GenRand32
is also the same size as
+Mt19937GenRand64
.
assert_eq!(2504, mem::size_of::<Mt19937GenRand32>());
+assert_eq!(mem::size_of::<Mt19937GenRand64>(), mem::size_of::<Mt19937GenRand32>());
Default seed used by Mt19937GenRand32::new_unseeded
.
Create a new Mersenne Twister random number generator using the given +seed.
+u32
seedlet seed = 123_456_789_u32;
+let mt1 = Mt19937GenRand32::new(seed);
+let mt2 = Mt19937GenRand32::from(seed.to_le_bytes());
+assert_eq!(mt1, mt2);
let mt1 = Mt19937GenRand32::new(Mt19937GenRand32::DEFAULT_SEED);
+let mt2 = Mt19937GenRand32::new_unseeded();
+assert_eq!(mt1, mt2);
Create a new Mersenne Twister random number generator using the given +key.
+Key can have any length.
+Create a new Mersenne Twister random number generator using the default +fixed seed.
+// Default MT seed
+let seed = 5489_u32;
+let mt = Mt19937GenRand32::new(seed);
+let unseeded = Mt19937GenRand32::new_unseeded();
+assert_eq!(mt, unseeded);
Generate next u64
output.
This function is implemented by generating two u32
s from the RNG and
+performing shifting and masking to turn them into a u64
output.
let mut mt = Mt19937GenRand32::new_unseeded();
+assert_ne!(mt.next_u64(), mt.next_u64());
Generate next u32
output.
u32
is the native output of the generator. This function advances the
+RNG step counter by one.
let mut mt = Mt19937GenRand32::new_unseeded();
+assert_ne!(mt.next_u32(), mt.next_u32());
Fill a buffer with bytes generated from the RNG.
+This method generates random u32
s (the native output unit of the RNG)
+until dest
is filled.
This method may discard some output bits if dest.len()
is not a
+multiple of 4.
let mut mt = Mt19937GenRand32::new_unseeded();
+let mut buf = [0; 32];
+mt.fill_bytes(&mut buf);
+assert_ne!([0; 32], buf);
+let mut buf = [0; 31];
+mt.fill_bytes(&mut buf);
+assert_ne!([0; 31], buf);
Attempt to recover the internal state of a Mersenne Twister using the +past 624 samples.
+This conversion takes a history of samples from a RNG and returns a +RNG that will produce identical output to the RNG that supplied the +samples.
+This constructor is also available as a TryFrom
implementation for
+&[u32]
.
If key
has less than 624 elements, an error is returned because there
+is not enough data to fully initialize the RNG.
If key
has more than 624 elements, an error is returned because the
+recovered RNG will not produce identical output to the RNG that supplied
+the samples.
Reseed a Mersenne Twister from a single u32
.
// Default MT seed
+let mut mt = Mt19937GenRand32::new_unseeded();
+let first = mt.next_u32();
+mt.fill_bytes(&mut [0; 512]);
+// Default MT seed
+mt.reseed(5489_u32);
+assert_eq!(first, mt.next_u32());
Reseed a Mersenne Twister from am iterator of u32
s.
Key can have any length.
+source
. Read moreReturn a new Mt19937GenRand32
with the default seed.
Equivalent to calling Mt19937GenRand32::new_unseeded
.
Construct a Mersenne Twister RNG from 4 bytes.
+The given bytes are treated as a little endian encoded u32
.
// Default MT seed
+let seed = 5489_u32.to_le_bytes();
+let mut mt = Mt19937GenRand32::from(seed);
+assert_ne!(mt.next_u32(), mt.next_u32());
This constructor is equivalent to passing a little endian encoded u32
.
// Default MT seed
+let seed = 5489_u32.to_le_bytes();
+let mt1 = Mt19937GenRand32::from(seed);
+let mt2 = Mt19937GenRand32::new(5489_u32);
+assert_eq!(mt1, mt2);
Construct a Mersenne Twister RNG from a u32
seed.
This function is equivalent to new
.
// Default MT seed
+let seed = 5489_u32;
+let mt1 = Mt19937GenRand32::from(seed);
+let mt2 = Mt19937GenRand32::new(seed);
+assert_eq!(mt1, mt2);
+
+// Non-default MT seed
+let seed = 9927_u32;
+let mt1 = Mt19937GenRand32::from(seed);
+let mt2 = Mt19937GenRand32::new(seed);
+assert_eq!(mt1, mt2);
Generate next u64
output.
This function is implemented by generating two u32
s from the RNG and
+performing shifting and masking to turn them into a u64
output.
use rand_core::RngCore;
+use rand_mt::Mt19937GenRand32;
+
+let mut rng = Mt19937GenRand32::new_unseeded();
+assert_ne!(rng.next_u64(), rng.next_u64());
Generate next u32
output.
u32
is the native output of the generator. This function advances the
+RNG step counter by one.
use rand_core::RngCore;
+use rand_mt::Mt19937GenRand32;
+
+let mut rng = Mt19937GenRand32::new_unseeded();
+assert_ne!(rng.next_u32(), rng.next_u32());
Fill a buffer with bytes generated from the RNG.
+This method generates random u32
s (the native output unit of the RNG)
+until dest
is filled.
This method may discard some output bits if dest.len()
is not a
+multiple of 4.
use rand_core::RngCore;
+use rand_mt::Mt19937GenRand32;
+
+let mut rng = Mt19937GenRand32::new_unseeded();
+let mut buf = [0; 32];
+rng.fill_bytes(&mut buf);
+assert_ne!([0; 32], buf);
+let mut buf = [0; 31];
+rng.fill_bytes(&mut buf);
+assert_ne!([0; 31], buf);
Fill a buffer with bytes generated from the RNG.
+This method generates random u32
s (the native output unit of the RNG)
+until dest
is filled.
This method may discard some output bits if dest.len()
is not a
+multiple of 4.
try_fill_bytes
is implemented with fill_bytes
+and is infallible.
use rand_core::RngCore;
+use rand_mt::Mt19937GenRand32;
+
+let mut rng = Mt19937GenRand32::new_unseeded();
+let mut buf = [0; 32];
+rng.try_fill_bytes(&mut buf)?;
+assert_ne!([0; 32], buf);
+let mut buf = [0; 31];
+rng.try_fill_bytes(&mut buf)?;
+assert_ne!([0; 31], buf);
Reseed from a little endian encoded u32
.
use rand_core::{RngCore, SeedableRng};
+use rand_mt::Mt19937GenRand32;
+
+// Default MT seed
+let seed = 5489_u32.to_le_bytes();
+let mut rng = Mt19937GenRand32::from_seed(seed);
+assert_ne!(rng.next_u32(), rng.next_u32());
u8
+arrays (we recommend [u8; N]
for some N
). Read moreu64
seed. Read moreAttempt to recover the internal state of a Mersenne Twister using the +past 624 samples.
+This conversion takes a history of samples from a RNG and returns a +RNG that will produce identical output to the RNG that supplied the +samples.
+This conversion is implemented with Mt19937GenRand32::recover
.
If key
has less than 624 elements, an error is returned because there
+is not enough data to fully initialize the RNG.
If key
has more than 624 elements, an error is returned because the
+recovered RNG will not produce identical output to the RNG that supplied
+the samples.
clone_to_uninit
)pub struct Mt19937GenRand64 { /* private fields */ }
The 64-bit flavor of the Mersenne Twister pseudorandom number +generator.
+Mt19937GenRand64
requires approximately 2.5 kilobytes of internal state.
You may wish to store an Mt19937GenRand64
on the heap in a Box
to make it
+easier to embed in another struct.
Mt19937GenRand64
is also the same size as
+Mt19937GenRand32
.
assert_eq!(2504, mem::size_of::<Mt19937GenRand64>());
+assert_eq!(mem::size_of::<Mt19937GenRand32>(), mem::size_of::<Mt19937GenRand64>());
Default seed used by Mt19937GenRand64::new_unseeded
.
Create a new Mersenne Twister random number generator using the given +seed.
+u64
seedlet seed = 123_456_789_u64;
+let mt1 = Mt19937GenRand64::new(seed);
+let mt2 = Mt19937GenRand64::from(seed.to_le_bytes());
+assert_eq!(mt1, mt2);
let mt1 = Mt19937GenRand64::new(Mt19937GenRand64::DEFAULT_SEED);
+let mt2 = Mt19937GenRand64::new_unseeded();
+assert_eq!(mt1, mt2);
Create a new Mersenne Twister random number generator using the given +key.
+Key can have any length.
+Create a new Mersenne Twister random number generator using the default +fixed seed.
+// Default MT seed
+let seed = 5489_u64;
+let mt = Mt19937GenRand64::new(seed);
+let unseeded = Mt19937GenRand64::new_unseeded();
+assert_eq!(mt, unseeded);
Generate next u64
output.
u64
is the native output of the generator. This function advances the
+RNG step counter by one.
let mut mt = Mt19937GenRand64::new_unseeded();
+assert_ne!(mt.next_u64(), mt.next_u64());
Generate next u32
output.
This function is implemented by generating one u64
from the RNG and
+performing shifting and masking to turn it into a u32
output.
let mut mt = Mt19937GenRand64::new_unseeded();
+assert_ne!(mt.next_u32(), mt.next_u32());
Fill a buffer with bytes generated from the RNG.
+This method generates random u64
s (the native output unit of the RNG)
+until dest
is filled.
This method may discard some output bits if dest.len()
is not a
+multiple of 8.
let mut mt = Mt19937GenRand64::new_unseeded();
+let mut buf = [0; 32];
+mt.fill_bytes(&mut buf);
+assert_ne!([0; 32], buf);
+let mut buf = [0; 31];
+mt.fill_bytes(&mut buf);
+assert_ne!([0; 31], buf);
Attempt to recover the internal state of a Mersenne Twister using the +past 312 samples.
+This conversion takes a history of samples from a RNG and returns a +RNG that will produce identical output to the RNG that supplied the +samples.
+This constructor is also available as a TryFrom
implementation for
+&[u32]
.
If key
has less than 312 elements, an error is returned because there
+is not enough data to fully initialize the RNG.
If key
has more than 312 elements, an error is returned because the
+recovered RNG will not produce identical output to the RNG that supplied
+the samples.
Reseed a Mersenne Twister from a single u64
.
// Default MT seed
+let mut mt = Mt19937GenRand64::new_unseeded();
+let first = mt.next_u64();
+mt.fill_bytes(&mut [0; 512]);
+// Default MT seed
+mt.reseed(5489_u64);
+assert_eq!(first, mt.next_u64());
Reseed a Mersenne Twister from am iterator of u64
s.
Key can have any length.
+source
. Read moreReturn a new Mt19937GenRand64
with the default seed.
Equivalent to calling Mt19937GenRand64::new_unseeded
.
Construct a Mersenne Twister RNG from a u64
seed.
This function is equivalent to new
.
// Default MT seed
+let seed = 5489_u64;
+let mt1 = Mt19937GenRand64::from(seed);
+let mt2 = Mt19937GenRand64::new(seed);
+assert_eq!(mt1, mt2);
+
+// Non-default MT seed
+let seed = 9927_u64;
+let mt1 = Mt19937GenRand64::from(seed);
+let mt2 = Mt19937GenRand64::new(seed);
+assert_eq!(mt1, mt2);
Generate next u64
output.
u64
is the native output of the generator. This function advances the
+RNG step counter by one.
use rand_core::RngCore;
+use rand_mt::Mt19937GenRand64;
+
+let mut rng = Mt19937GenRand64::new_unseeded();
+assert_ne!(rng.next_u64(), rng.next_u64());
Generate next u32
output.
This function is implemented by generating one u64
from the RNG and
+performing shifting and masking to turn it into a u32
output.
use rand_core::RngCore;
+use rand_mt::Mt19937GenRand64;
+
+let mut rng = Mt19937GenRand64::new_unseeded();
+assert_ne!(rng.next_u32(), rng.next_u32());
Fill a buffer with bytes generated from the RNG.
+This method generates random u64
s (the native output unit of the RNG)
+until dest
is filled.
This method may discard some output bits if dest.len()
is not a
+multiple of 8.
use rand_core::RngCore;
+use rand_mt::Mt19937GenRand64;
+
+let mut rng = Mt19937GenRand64::new_unseeded();
+let mut buf = [0; 32];
+rng.fill_bytes(&mut buf);
+assert_ne!([0; 32], buf);
+let mut buf = [0; 31];
+rng.fill_bytes(&mut buf);
+assert_ne!([0; 31], buf);
Fill a buffer with bytes generated from the RNG.
+This method generates random u64
s (the native output unit of the RNG)
+until dest
is filled.
This method may discard some output bits if dest.len()
is not a
+multiple of 8.
try_fill_bytes
is implemented with fill_bytes
+and is infallible.
use rand_core::RngCore;
+use rand_mt::Mt19937GenRand64;
+
+let mut rng = Mt19937GenRand64::new_unseeded();
+let mut buf = [0; 32];
+rng.try_fill_bytes(&mut buf)?;
+assert_ne!([0; 32], buf);
+let mut buf = [0; 31];
+rng.try_fill_bytes(&mut buf)?;
+assert_ne!([0; 31], buf);
Reseed from a little endian encoded u64
.
// Default MT seed
+let seed = 5489_u64.to_le_bytes();
+let mut mt = Mt19937GenRand64::from_seed(seed);
+assert_ne!(mt.next_u64(), mt.next_u64());
u8
+arrays (we recommend [u8; N]
for some N
). Read moreu64
seed. Read moreAttempt to recover the internal state of a Mersenne Twister using the +past 312 samples.
+This conversion takes a history of samples from a RNG and returns a +RNG that will produce identical output to the RNG that supplied the +samples.
+This conversion is implemented with Mt19937GenRand64::recover
.
If key
has less than 312 elements, an error is returned because there
+is not enough data to fully initialize the RNG.
If key
has more than 312 elements, an error is returned because the
+recovered RNG will not produce identical output to the RNG that supplied
+the samples.
clone_to_uninit
)pub type Mt = Mt19937GenRand32;
A type alias for Mt19937GenRand32
, 32-bit Mersenne Twister.
struct Mt { /* private fields */ }
pub type Mt64 = Mt19937GenRand64;
A type alias for Mt19937GenRand64
, 64-bit Mersenne Twister.
struct Mt64 { /* private fields */ }
RngCore
or …\nAn extension trait that is automatically implemented for …\nError type of random number generators\nCodes below this point represent OS Errors (i.e. positive …\nThe core of a random number generator.\nSeed type, which is restricted to types …\nA random number generator that can be explicitly seeded.\nUpcast to an RngCore
trait object.\nThe BlockRngCore
trait and implementation helpers\nRetrieve the error code, if any.\nFill dest
with random data.\nReturns the argument unchanged.\nCreate a new PRNG seeded from another Rng
.\nCreate a new PRNG using the given seed.\nHelper functions for implementing RngCore
functions.\nCalls U::from(self)
.\nLittle-Endian utilities\nReturn the next random u32
.\nReturn the next random u64
.\nExtract the raw OS error code (if this error came from the …\nCreate a new PRNG using a u64
seed.\nFill dest
entirely with random data.\nA wrapper type implementing RngCore
for some type …\nA wrapper type implementing RngCore
for some type …\nA trait for RNGs which do not generate random numbers …\nResults element type, e.g. u32
.\nResults type. This is the ‘block’ an RNG implementing …\nThe core part of the RNG, implementing the generate
…\nThe core part of the RNG, implementing the generate
…\nReturns the argument unchanged.\nReturns the argument unchanged.\nGenerate a new block of results.\nGenerate a new set of results immediately, setting the …\nGenerate a new set of results immediately, setting the …\nGet the index into the result buffer.\nGet the index into the result buffer.\nCalls U::from(self)
.\nCalls U::from(self)
.\nCreate a new BlockRng
from an existing RNG implementing …\nCreate a new BlockRng
from an existing RNG implementing …\nReset the number of available results. This will force a …\nReset the number of available results. This will force a …\nImplement fill_bytes
via next_u64
and next_u32
, …\nImplement fill_bytes
by reading chunks from the output …\nImplement fill_bytes
by reading chunks from the output …\nImplement next_u32
via fill_bytes
, little-endian order.\nImplement next_u64
via fill_bytes
, little-endian order.\nImplement next_u64
via next_u32
, little-endian order.\nReads unsigned 32 bit integers from src
into dst
.\nReads unsigned 64 bit integers from src
into dst
.")
\ No newline at end of file
diff --git a/search.desc/rand_mt/rand_mt-desc-0-.js b/search.desc/rand_mt/rand_mt-desc-0-.js
new file mode 100644
index 000000000..bcea1d585
--- /dev/null
+++ b/search.desc/rand_mt/rand_mt-desc-0-.js
@@ -0,0 +1 @@
+searchState.loadedDescShard("rand_mt", 0, "Mersenne Twister random number generators.\nDefault seed used by Mt19937GenRand32::new_unseeded
.\nDefault seed used by Mt19937GenRand64::new_unseeded
.\nA type alias for Mt19937GenRand32
, 32-bit Mersenne Twister.\nThe 32-bit flavor of the Mersenne Twister pseudorandom …\nThe 64-bit flavor of the Mersenne Twister pseudorandom …\nA type alias for Mt19937GenRand64
, 64-bit Mersenne Twister.\nError returned from fallible Mersenne Twister recovery …\nAttempted to recover an RNG with too many samples.\nAttempted to recover an RNG with too few samples.\nReturn a new Mt19937GenRand32
with the default seed.\nReturn a new Mt19937GenRand64
with the default seed.\nFill a buffer with bytes generated from the RNG.\nFill a buffer with bytes generated from the RNG.\nFill a buffer with bytes generated from the RNG.\nFill a buffer with bytes generated from the RNG.\nConstruct a Mersenne Twister RNG from a u32
seed.\nRecover the internal state of a Mersenne Twister using the …\nReturns the argument unchanged.\nConstruct a Mersenne Twister RNG from 4 bytes.\nReturns the argument unchanged.\nRecover the internal state of a Mersenne Twister using the …\nConstruct a Mersenne Twister RNG from a u64
seed.\nConstruct a Mersenne Twister RNG from 8 bytes.\nReturns the argument unchanged.\nReseed from a little endian encoded u32
.\nReseed from a little endian encoded u64
.\nCalls U::from(self)
.\nCalls U::from(self)
.\nCalls U::from(self)
.\nCreate a new Mersenne Twister random number generator …\nCreate a new Mersenne Twister random number generator …\nCreate a new Mersenne Twister random number generator …\nCreate a new Mersenne Twister random number generator …\nCreate a new Mersenne Twister random number generator …\nCreate a new Mersenne Twister random number generator …\nGenerate next u32
output.\nGenerate next u32
output.\nGenerate next u32
output.\nGenerate next u32
output.\nGenerate next u64
output.\nGenerate next u64
output.\nGenerate next u64
output.\nGenerate next u64
output.\nAttempt to recover the internal state of a Mersenne …\nAttempt to recover the internal state of a Mersenne …\nReseed a Mersenne Twister from a single u32
.\nReseed a Mersenne Twister from a single u64
.\nReseed a Mersenne Twister from am iterator of u32
s.\nReseed a Mersenne Twister from am iterator of u64
s.\nFill a buffer with bytes generated from the RNG.\nFill a buffer with bytes generated from the RNG.\nAttempt to recover the internal state of a Mersenne …\nAttempt to recover the internal state of a Mersenne …")
\ No newline at end of file
diff --git a/settings.html b/settings.html
new file mode 100644
index 000000000..853b591c7
--- /dev/null
+++ b/settings.html
@@ -0,0 +1 @@
++1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539
// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The `BlockRngCore` trait and implementation helpers
+//!
+//! The [`BlockRngCore`] trait exists to assist in the implementation of RNGs
+//! which generate a block of data in a cache instead of returning generated
+//! values directly.
+//!
+//! Usage of this trait is optional, but provides two advantages:
+//! implementations only need to concern themselves with generation of the
+//! block, not the various [`RngCore`] methods (especially [`fill_bytes`], where
+//! the optimal implementations are not trivial), and this allows
+//! `ReseedingRng` (see [`rand`](https://docs.rs/rand) crate) perform periodic
+//! reseeding with very low overhead.
+//!
+//! # Example
+//!
+//! ```no_run
+//! use rand_core::{RngCore, SeedableRng};
+//! use rand_core::block::{BlockRngCore, BlockRng};
+//!
+//! struct MyRngCore;
+//!
+//! impl BlockRngCore for MyRngCore {
+//! type Item = u32;
+//! type Results = [u32; 16];
+//!
+//! fn generate(&mut self, results: &mut Self::Results) {
+//! unimplemented!()
+//! }
+//! }
+//!
+//! impl SeedableRng for MyRngCore {
+//! type Seed = [u8; 32];
+//! fn from_seed(seed: Self::Seed) -> Self {
+//! unimplemented!()
+//! }
+//! }
+//!
+//! // optionally, also implement CryptoRng for MyRngCore
+//!
+//! // Final RNG.
+//! let mut rng = BlockRng::<MyRngCore>::seed_from_u64(0);
+//! println!("First value: {}", rng.next_u32());
+//! ```
+//!
+//! [`BlockRngCore`]: crate::block::BlockRngCore
+//! [`fill_bytes`]: RngCore::fill_bytes
+
+use crate::impls::{fill_via_u32_chunks, fill_via_u64_chunks};
+use crate::{CryptoRng, Error, RngCore, SeedableRng};
+use core::convert::AsRef;
+use core::fmt;
+#[cfg(feature = "serde1")]
+use serde::{Deserialize, Serialize};
+
+/// A trait for RNGs which do not generate random numbers individually, but in
+/// blocks (typically `[u32; N]`). This technique is commonly used by
+/// cryptographic RNGs to improve performance.
+///
+/// See the [module][crate::block] documentation for details.
+pub trait BlockRngCore {
+ /// Results element type, e.g. `u32`.
+ type Item;
+
+ /// Results type. This is the 'block' an RNG implementing `BlockRngCore`
+ /// generates, which will usually be an array like `[u32; 16]`.
+ type Results: AsRef<[Self::Item]> + AsMut<[Self::Item]> + Default;
+
+ /// Generate a new block of results.
+ fn generate(&mut self, results: &mut Self::Results);
+}
+
+/// A wrapper type implementing [`RngCore`] for some type implementing
+/// [`BlockRngCore`] with `u32` array buffer; i.e. this can be used to implement
+/// a full RNG from just a `generate` function.
+///
+/// The `core` field may be accessed directly but the results buffer may not.
+/// PRNG implementations can simply use a type alias
+/// (`pub type MyRng = BlockRng<MyRngCore>;`) but might prefer to use a
+/// wrapper type (`pub struct MyRng(BlockRng<MyRngCore>);`); the latter must
+/// re-implement `RngCore` but hides the implementation details and allows
+/// extra functionality to be defined on the RNG
+/// (e.g. `impl MyRng { fn set_stream(...){...} }`).
+///
+/// `BlockRng` has heavily optimized implementations of the [`RngCore`] methods
+/// reading values from the results buffer, as well as
+/// calling [`BlockRngCore::generate`] directly on the output array when
+/// [`fill_bytes`] / [`try_fill_bytes`] is called on a large array. These methods
+/// also handle the bookkeeping of when to generate a new batch of values.
+///
+/// No whole generated `u32` values are thrown away and all values are consumed
+/// in-order. [`next_u32`] simply takes the next available `u32` value.
+/// [`next_u64`] is implemented by combining two `u32` values, least
+/// significant first. [`fill_bytes`] and [`try_fill_bytes`] consume a whole
+/// number of `u32` values, converting each `u32` to a byte slice in
+/// little-endian order. If the requested byte length is not a multiple of 4,
+/// some bytes will be discarded.
+///
+/// See also [`BlockRng64`] which uses `u64` array buffers. Currently there is
+/// no direct support for other buffer types.
+///
+/// For easy initialization `BlockRng` also implements [`SeedableRng`].
+///
+/// [`next_u32`]: RngCore::next_u32
+/// [`next_u64`]: RngCore::next_u64
+/// [`fill_bytes`]: RngCore::fill_bytes
+/// [`try_fill_bytes`]: RngCore::try_fill_bytes
+#[derive(Clone)]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
+#[cfg_attr(
+ feature = "serde1",
+ serde(
+ bound = "for<'x> R: Serialize + Deserialize<'x> + Sized, for<'x> R::Results: Serialize + Deserialize<'x>"
+ )
+)]
+pub struct BlockRng<R: BlockRngCore + ?Sized> {
+ results: R::Results,
+ index: usize,
+ /// The *core* part of the RNG, implementing the `generate` function.
+ pub core: R,
+}
+
+// Custom Debug implementation that does not expose the contents of `results`.
+impl<R: BlockRngCore + fmt::Debug> fmt::Debug for BlockRng<R> {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fmt.debug_struct("BlockRng")
+ .field("core", &self.core)
+ .field("result_len", &self.results.as_ref().len())
+ .field("index", &self.index)
+ .finish()
+ }
+}
+
+impl<R: BlockRngCore> BlockRng<R> {
+ /// Create a new `BlockRng` from an existing RNG implementing
+ /// `BlockRngCore`. Results will be generated on first use.
+ #[inline]
+ pub fn new(core: R) -> BlockRng<R> {
+ let results_empty = R::Results::default();
+ BlockRng {
+ core,
+ index: results_empty.as_ref().len(),
+ results: results_empty,
+ }
+ }
+
+ /// Get the index into the result buffer.
+ ///
+ /// If this is equal to or larger than the size of the result buffer then
+ /// the buffer is "empty" and `generate()` must be called to produce new
+ /// results.
+ #[inline(always)]
+ pub fn index(&self) -> usize {
+ self.index
+ }
+
+ /// Reset the number of available results.
+ /// This will force a new set of results to be generated on next use.
+ #[inline]
+ pub fn reset(&mut self) {
+ self.index = self.results.as_ref().len();
+ }
+
+ /// Generate a new set of results immediately, setting the index to the
+ /// given value.
+ #[inline]
+ pub fn generate_and_set(&mut self, index: usize) {
+ assert!(index < self.results.as_ref().len());
+ self.core.generate(&mut self.results);
+ self.index = index;
+ }
+}
+
+impl<R: BlockRngCore<Item = u32>> RngCore for BlockRng<R>
+where
+ <R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]>,
+{
+ #[inline]
+ fn next_u32(&mut self) -> u32 {
+ if self.index >= self.results.as_ref().len() {
+ self.generate_and_set(0);
+ }
+
+ let value = self.results.as_ref()[self.index];
+ self.index += 1;
+ value
+ }
+
+ #[inline]
+ fn next_u64(&mut self) -> u64 {
+ let read_u64 = |results: &[u32], index| {
+ let data = &results[index..=index + 1];
+ u64::from(data[1]) << 32 | u64::from(data[0])
+ };
+
+ let len = self.results.as_ref().len();
+
+ let index = self.index;
+ if index < len - 1 {
+ self.index += 2;
+ // Read an u64 from the current index
+ read_u64(self.results.as_ref(), index)
+ } else if index >= len {
+ self.generate_and_set(2);
+ read_u64(self.results.as_ref(), 0)
+ } else {
+ let x = u64::from(self.results.as_ref()[len - 1]);
+ self.generate_and_set(1);
+ let y = u64::from(self.results.as_ref()[0]);
+ (y << 32) | x
+ }
+ }
+
+ #[inline]
+ fn fill_bytes(&mut self, dest: &mut [u8]) {
+ let mut read_len = 0;
+ while read_len < dest.len() {
+ if self.index >= self.results.as_ref().len() {
+ self.generate_and_set(0);
+ }
+ let (consumed_u32, filled_u8) =
+ fill_via_u32_chunks(&self.results.as_ref()[self.index..], &mut dest[read_len..]);
+
+ self.index += consumed_u32;
+ read_len += filled_u8;
+ }
+ }
+
+ #[inline(always)]
+ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+ self.fill_bytes(dest);
+ Ok(())
+ }
+}
+
+impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng<R> {
+ type Seed = R::Seed;
+
+ #[inline(always)]
+ fn from_seed(seed: Self::Seed) -> Self {
+ Self::new(R::from_seed(seed))
+ }
+
+ #[inline(always)]
+ fn seed_from_u64(seed: u64) -> Self {
+ Self::new(R::seed_from_u64(seed))
+ }
+
+ #[inline(always)]
+ fn from_rng<S: RngCore>(rng: S) -> Result<Self, Error> {
+ Ok(Self::new(R::from_rng(rng)?))
+ }
+}
+
+/// A wrapper type implementing [`RngCore`] for some type implementing
+/// [`BlockRngCore`] with `u64` array buffer; i.e. this can be used to implement
+/// a full RNG from just a `generate` function.
+///
+/// This is similar to [`BlockRng`], but specialized for algorithms that operate
+/// on `u64` values.
+///
+/// No whole generated `u64` values are thrown away and all values are consumed
+/// in-order. [`next_u64`] simply takes the next available `u64` value.
+/// [`next_u32`] is however a bit special: half of a `u64` is consumed, leaving
+/// the other half in the buffer. If the next function called is [`next_u32`]
+/// then the other half is then consumed, however both [`next_u64`] and
+/// [`fill_bytes`] discard the rest of any half-consumed `u64`s when called.
+///
+/// [`fill_bytes`] and [`try_fill_bytes`] consume a whole number of `u64`
+/// values. If the requested length is not a multiple of 8, some bytes will be
+/// discarded.
+///
+/// [`next_u32`]: RngCore::next_u32
+/// [`next_u64`]: RngCore::next_u64
+/// [`fill_bytes`]: RngCore::fill_bytes
+/// [`try_fill_bytes`]: RngCore::try_fill_bytes
+#[derive(Clone)]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
+pub struct BlockRng64<R: BlockRngCore + ?Sized> {
+ results: R::Results,
+ index: usize,
+ half_used: bool, // true if only half of the previous result is used
+ /// The *core* part of the RNG, implementing the `generate` function.
+ pub core: R,
+}
+
+// Custom Debug implementation that does not expose the contents of `results`.
+impl<R: BlockRngCore + fmt::Debug> fmt::Debug for BlockRng64<R> {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fmt.debug_struct("BlockRng64")
+ .field("core", &self.core)
+ .field("result_len", &self.results.as_ref().len())
+ .field("index", &self.index)
+ .field("half_used", &self.half_used)
+ .finish()
+ }
+}
+
+impl<R: BlockRngCore> BlockRng64<R> {
+ /// Create a new `BlockRng` from an existing RNG implementing
+ /// `BlockRngCore`. Results will be generated on first use.
+ #[inline]
+ pub fn new(core: R) -> BlockRng64<R> {
+ let results_empty = R::Results::default();
+ BlockRng64 {
+ core,
+ index: results_empty.as_ref().len(),
+ half_used: false,
+ results: results_empty,
+ }
+ }
+
+ /// Get the index into the result buffer.
+ ///
+ /// If this is equal to or larger than the size of the result buffer then
+ /// the buffer is "empty" and `generate()` must be called to produce new
+ /// results.
+ #[inline(always)]
+ pub fn index(&self) -> usize {
+ self.index
+ }
+
+ /// Reset the number of available results.
+ /// This will force a new set of results to be generated on next use.
+ #[inline]
+ pub fn reset(&mut self) {
+ self.index = self.results.as_ref().len();
+ self.half_used = false;
+ }
+
+ /// Generate a new set of results immediately, setting the index to the
+ /// given value.
+ #[inline]
+ pub fn generate_and_set(&mut self, index: usize) {
+ assert!(index < self.results.as_ref().len());
+ self.core.generate(&mut self.results);
+ self.index = index;
+ self.half_used = false;
+ }
+}
+
+impl<R: BlockRngCore<Item = u64>> RngCore for BlockRng64<R>
+where
+ <R as BlockRngCore>::Results: AsRef<[u64]> + AsMut<[u64]>,
+{
+ #[inline]
+ fn next_u32(&mut self) -> u32 {
+ let mut index = self.index - self.half_used as usize;
+ if index >= self.results.as_ref().len() {
+ self.core.generate(&mut self.results);
+ self.index = 0;
+ index = 0;
+ // `self.half_used` is by definition `false`
+ self.half_used = false;
+ }
+
+ let shift = 32 * (self.half_used as usize);
+
+ self.half_used = !self.half_used;
+ self.index += self.half_used as usize;
+
+ (self.results.as_ref()[index] >> shift) as u32
+ }
+
+ #[inline]
+ fn next_u64(&mut self) -> u64 {
+ if self.index >= self.results.as_ref().len() {
+ self.core.generate(&mut self.results);
+ self.index = 0;
+ }
+
+ let value = self.results.as_ref()[self.index];
+ self.index += 1;
+ self.half_used = false;
+ value
+ }
+
+ #[inline]
+ fn fill_bytes(&mut self, dest: &mut [u8]) {
+ let mut read_len = 0;
+ self.half_used = false;
+ while read_len < dest.len() {
+ if self.index as usize >= self.results.as_ref().len() {
+ self.core.generate(&mut self.results);
+ self.index = 0;
+ }
+
+ let (consumed_u64, filled_u8) = fill_via_u64_chunks(
+ &self.results.as_ref()[self.index as usize..],
+ &mut dest[read_len..],
+ );
+
+ self.index += consumed_u64;
+ read_len += filled_u8;
+ }
+ }
+
+ #[inline(always)]
+ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+ self.fill_bytes(dest);
+ Ok(())
+ }
+}
+
+impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng64<R> {
+ type Seed = R::Seed;
+
+ #[inline(always)]
+ fn from_seed(seed: Self::Seed) -> Self {
+ Self::new(R::from_seed(seed))
+ }
+
+ #[inline(always)]
+ fn seed_from_u64(seed: u64) -> Self {
+ Self::new(R::seed_from_u64(seed))
+ }
+
+ #[inline(always)]
+ fn from_rng<S: RngCore>(rng: S) -> Result<Self, Error> {
+ Ok(Self::new(R::from_rng(rng)?))
+ }
+}
+
+impl<R: BlockRngCore + CryptoRng> CryptoRng for BlockRng<R> {}
+
+#[cfg(test)]
+mod test {
+ use crate::{SeedableRng, RngCore};
+ use crate::block::{BlockRng, BlockRng64, BlockRngCore};
+
+ #[derive(Debug, Clone)]
+ struct DummyRng {
+ counter: u32,
+ }
+
+ impl BlockRngCore for DummyRng {
+ type Item = u32;
+
+ type Results = [u32; 16];
+
+ fn generate(&mut self, results: &mut Self::Results) {
+ for r in results {
+ *r = self.counter;
+ self.counter = self.counter.wrapping_add(3511615421);
+ }
+ }
+ }
+
+ impl SeedableRng for DummyRng {
+ type Seed = [u8; 4];
+
+ fn from_seed(seed: Self::Seed) -> Self {
+ DummyRng { counter: u32::from_le_bytes(seed) }
+ }
+ }
+
+ #[test]
+ fn blockrng_next_u32_vs_next_u64() {
+ let mut rng1 = BlockRng::<DummyRng>::from_seed([1, 2, 3, 4]);
+ let mut rng2 = rng1.clone();
+ let mut rng3 = rng1.clone();
+
+ let mut a = [0; 16];
+ (&mut a[..4]).copy_from_slice(&rng1.next_u32().to_le_bytes());
+ (&mut a[4..12]).copy_from_slice(&rng1.next_u64().to_le_bytes());
+ (&mut a[12..]).copy_from_slice(&rng1.next_u32().to_le_bytes());
+
+ let mut b = [0; 16];
+ (&mut b[..4]).copy_from_slice(&rng2.next_u32().to_le_bytes());
+ (&mut b[4..8]).copy_from_slice(&rng2.next_u32().to_le_bytes());
+ (&mut b[8..]).copy_from_slice(&rng2.next_u64().to_le_bytes());
+ assert_eq!(a, b);
+
+ let mut c = [0; 16];
+ (&mut c[..8]).copy_from_slice(&rng3.next_u64().to_le_bytes());
+ (&mut c[8..12]).copy_from_slice(&rng3.next_u32().to_le_bytes());
+ (&mut c[12..]).copy_from_slice(&rng3.next_u32().to_le_bytes());
+ assert_eq!(a, c);
+ }
+
+ #[derive(Debug, Clone)]
+ struct DummyRng64 {
+ counter: u64,
+ }
+
+ impl BlockRngCore for DummyRng64 {
+ type Item = u64;
+
+ type Results = [u64; 8];
+
+ fn generate(&mut self, results: &mut Self::Results) {
+ for r in results {
+ *r = self.counter;
+ self.counter = self.counter.wrapping_add(2781463553396133981);
+ }
+ }
+ }
+
+ impl SeedableRng for DummyRng64 {
+ type Seed = [u8; 8];
+
+ fn from_seed(seed: Self::Seed) -> Self {
+ DummyRng64 { counter: u64::from_le_bytes(seed) }
+ }
+ }
+
+ #[test]
+ fn blockrng64_next_u32_vs_next_u64() {
+ let mut rng1 = BlockRng64::<DummyRng64>::from_seed([1, 2, 3, 4, 5, 6, 7, 8]);
+ let mut rng2 = rng1.clone();
+ let mut rng3 = rng1.clone();
+
+ let mut a = [0; 16];
+ (&mut a[..4]).copy_from_slice(&rng1.next_u32().to_le_bytes());
+ (&mut a[4..12]).copy_from_slice(&rng1.next_u64().to_le_bytes());
+ (&mut a[12..]).copy_from_slice(&rng1.next_u32().to_le_bytes());
+
+ let mut b = [0; 16];
+ (&mut b[..4]).copy_from_slice(&rng2.next_u32().to_le_bytes());
+ (&mut b[4..8]).copy_from_slice(&rng2.next_u32().to_le_bytes());
+ (&mut b[8..]).copy_from_slice(&rng2.next_u64().to_le_bytes());
+ assert_ne!(a, b);
+ assert_eq!(&a[..4], &b[..4]);
+ assert_eq!(&a[4..12], &b[8..]);
+
+ let mut c = [0; 16];
+ (&mut c[..8]).copy_from_slice(&rng3.next_u64().to_le_bytes());
+ (&mut c[8..12]).copy_from_slice(&rng3.next_u32().to_le_bytes());
+ (&mut c[12..]).copy_from_slice(&rng3.next_u32().to_le_bytes());
+ assert_eq!(b, c);
+ }
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228
// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Error types
+
+use core::fmt;
+use core::num::NonZeroU32;
+
+#[cfg(feature = "std")] use std::boxed::Box;
+
+/// Error type of random number generators
+///
+/// In order to be compatible with `std` and `no_std`, this type has two
+/// possible implementations: with `std` a boxed `Error` trait object is stored,
+/// while with `no_std` we merely store an error code.
+pub struct Error {
+ #[cfg(feature = "std")]
+ inner: Box<dyn std::error::Error + Send + Sync + 'static>,
+ #[cfg(not(feature = "std"))]
+ code: NonZeroU32,
+}
+
+impl Error {
+ /// Codes at or above this point can be used by users to define their own
+ /// custom errors.
+ ///
+ /// This has a fixed value of `(1 << 31) + (1 << 30) = 0xC000_0000`,
+ /// therefore the number of values available for custom codes is `1 << 30`.
+ ///
+ /// This is identical to [`getrandom::Error::CUSTOM_START`](https://docs.rs/getrandom/latest/getrandom/struct.Error.html#associatedconstant.CUSTOM_START).
+ pub const CUSTOM_START: u32 = (1 << 31) + (1 << 30);
+ /// Codes below this point represent OS Errors (i.e. positive i32 values).
+ /// Codes at or above this point, but below [`Error::CUSTOM_START`] are
+ /// reserved for use by the `rand` and `getrandom` crates.
+ ///
+ /// This is identical to [`getrandom::Error::INTERNAL_START`](https://docs.rs/getrandom/latest/getrandom/struct.Error.html#associatedconstant.INTERNAL_START).
+ pub const INTERNAL_START: u32 = 1 << 31;
+
+ /// Construct from any type supporting `std::error::Error`
+ ///
+ /// Available only when configured with `std`.
+ ///
+ /// See also `From<NonZeroU32>`, which is available with and without `std`.
+ #[cfg(feature = "std")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
+ #[inline]
+ pub fn new<E>(err: E) -> Self
+ where
+ E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
+ {
+ Error { inner: err.into() }
+ }
+
+ /// Reference the inner error (`std` only)
+ ///
+ /// When configured with `std`, this is a trivial operation and never
+ /// panics. Without `std`, this method is simply unavailable.
+ #[cfg(feature = "std")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
+ #[inline]
+ pub fn inner(&self) -> &(dyn std::error::Error + Send + Sync + 'static) {
+ &*self.inner
+ }
+
+ /// Unwrap the inner error (`std` only)
+ ///
+ /// When configured with `std`, this is a trivial operation and never
+ /// panics. Without `std`, this method is simply unavailable.
+ #[cfg(feature = "std")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
+ #[inline]
+ pub fn take_inner(self) -> Box<dyn std::error::Error + Send + Sync + 'static> {
+ self.inner
+ }
+
+ /// Extract the raw OS error code (if this error came from the OS)
+ ///
+ /// This method is identical to `std::io::Error::raw_os_error()`, except
+ /// that it works in `no_std` contexts. If this method returns `None`, the
+ /// error value can still be formatted via the `Display` implementation.
+ #[inline]
+ pub fn raw_os_error(&self) -> Option<i32> {
+ #[cfg(feature = "std")]
+ {
+ if let Some(e) = self.inner.downcast_ref::<std::io::Error>() {
+ return e.raw_os_error();
+ }
+ }
+ match self.code() {
+ Some(code) if u32::from(code) < Self::INTERNAL_START => Some(u32::from(code) as i32),
+ _ => None,
+ }
+ }
+
+ /// Retrieve the error code, if any.
+ ///
+ /// If this `Error` was constructed via `From<NonZeroU32>`, then this method
+ /// will return this `NonZeroU32` code (for `no_std` this is always the
+ /// case). Otherwise, this method will return `None`.
+ #[inline]
+ pub fn code(&self) -> Option<NonZeroU32> {
+ #[cfg(feature = "std")]
+ {
+ self.inner.downcast_ref::<ErrorCode>().map(|c| c.0)
+ }
+ #[cfg(not(feature = "std"))]
+ {
+ Some(self.code)
+ }
+ }
+}
+
+impl fmt::Debug for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ #[cfg(feature = "std")]
+ {
+ write!(f, "Error {{ inner: {:?} }}", self.inner)
+ }
+ #[cfg(all(feature = "getrandom", not(feature = "std")))]
+ {
+ getrandom::Error::from(self.code).fmt(f)
+ }
+ #[cfg(not(feature = "getrandom"))]
+ {
+ write!(f, "Error {{ code: {} }}", self.code)
+ }
+ }
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ #[cfg(feature = "std")]
+ {
+ write!(f, "{}", self.inner)
+ }
+ #[cfg(all(feature = "getrandom", not(feature = "std")))]
+ {
+ getrandom::Error::from(self.code).fmt(f)
+ }
+ #[cfg(not(feature = "getrandom"))]
+ {
+ write!(f, "error code {}", self.code)
+ }
+ }
+}
+
+impl From<NonZeroU32> for Error {
+ #[inline]
+ fn from(code: NonZeroU32) -> Self {
+ #[cfg(feature = "std")]
+ {
+ Error {
+ inner: Box::new(ErrorCode(code)),
+ }
+ }
+ #[cfg(not(feature = "std"))]
+ {
+ Error { code }
+ }
+ }
+}
+
+#[cfg(feature = "getrandom")]
+impl From<getrandom::Error> for Error {
+ #[inline]
+ fn from(error: getrandom::Error) -> Self {
+ #[cfg(feature = "std")]
+ {
+ Error {
+ inner: Box::new(error),
+ }
+ }
+ #[cfg(not(feature = "std"))]
+ {
+ Error { code: error.code() }
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for Error {
+ #[inline]
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ self.inner.source()
+ }
+}
+
+#[cfg(feature = "std")]
+impl From<Error> for std::io::Error {
+ #[inline]
+ fn from(error: Error) -> Self {
+ if let Some(code) = error.raw_os_error() {
+ std::io::Error::from_raw_os_error(code)
+ } else {
+ std::io::Error::new(std::io::ErrorKind::Other, error)
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+#[derive(Debug, Copy, Clone)]
+struct ErrorCode(NonZeroU32);
+
+#[cfg(feature = "std")]
+impl fmt::Display for ErrorCode {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "error code {}", self.0)
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for ErrorCode {}
+
+#[cfg(test)]
+mod test {
+ #[cfg(feature = "getrandom")]
+ #[test]
+ fn test_error_codes() {
+ // Make sure the values are the same as in `getrandom`.
+ assert_eq!(super::Error::CUSTOM_START, getrandom::Error::CUSTOM_START);
+ assert_eq!(super::Error::INTERNAL_START, getrandom::Error::INTERNAL_START);
+ }
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207
// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Helper functions for implementing `RngCore` functions.
+//!
+//! For cross-platform reproducibility, these functions all use Little Endian:
+//! least-significant part first. For example, `next_u64_via_u32` takes `u32`
+//! values `x, y`, then outputs `(y << 32) | x`. To implement `next_u32`
+//! from `next_u64` in little-endian order, one should use `next_u64() as u32`.
+//!
+//! Byte-swapping (like the std `to_le` functions) is only needed to convert
+//! to/from byte sequences, and since its purpose is reproducibility,
+//! non-reproducible sources (e.g. `OsRng`) need not bother with it.
+
+use crate::RngCore;
+use core::cmp::min;
+
+/// Implement `next_u64` via `next_u32`, little-endian order.
+pub fn next_u64_via_u32<R: RngCore + ?Sized>(rng: &mut R) -> u64 {
+ // Use LE; we explicitly generate one value before the next.
+ let x = u64::from(rng.next_u32());
+ let y = u64::from(rng.next_u32());
+ (y << 32) | x
+}
+
+/// Implement `fill_bytes` via `next_u64` and `next_u32`, little-endian order.
+///
+/// The fastest way to fill a slice is usually to work as long as possible with
+/// integers. That is why this method mostly uses `next_u64`, and only when
+/// there are 4 or less bytes remaining at the end of the slice it uses
+/// `next_u32` once.
+pub fn fill_bytes_via_next<R: RngCore + ?Sized>(rng: &mut R, dest: &mut [u8]) {
+ let mut left = dest;
+ while left.len() >= 8 {
+ let (l, r) = { left }.split_at_mut(8);
+ left = r;
+ let chunk: [u8; 8] = rng.next_u64().to_le_bytes();
+ l.copy_from_slice(&chunk);
+ }
+ let n = left.len();
+ if n > 4 {
+ let chunk: [u8; 8] = rng.next_u64().to_le_bytes();
+ left.copy_from_slice(&chunk[..n]);
+ } else if n > 0 {
+ let chunk: [u8; 4] = rng.next_u32().to_le_bytes();
+ left.copy_from_slice(&chunk[..n]);
+ }
+}
+
+trait Observable: Copy {
+ type Bytes: AsRef<[u8]>;
+ fn to_le_bytes(self) -> Self::Bytes;
+
+ // Contract: observing self is memory-safe (implies no uninitialised padding)
+ fn as_byte_slice(x: &[Self]) -> &[u8];
+}
+impl Observable for u32 {
+ type Bytes = [u8; 4];
+ fn to_le_bytes(self) -> Self::Bytes {
+ self.to_le_bytes()
+ }
+ fn as_byte_slice(x: &[Self]) -> &[u8] {
+ let ptr = x.as_ptr() as *const u8;
+ let len = x.len() * core::mem::size_of::<Self>();
+ unsafe { core::slice::from_raw_parts(ptr, len) }
+ }
+}
+impl Observable for u64 {
+ type Bytes = [u8; 8];
+ fn to_le_bytes(self) -> Self::Bytes {
+ self.to_le_bytes()
+ }
+ fn as_byte_slice(x: &[Self]) -> &[u8] {
+ let ptr = x.as_ptr() as *const u8;
+ let len = x.len() * core::mem::size_of::<Self>();
+ unsafe { core::slice::from_raw_parts(ptr, len) }
+ }
+}
+
+fn fill_via_chunks<T: Observable>(src: &[T], dest: &mut [u8]) -> (usize, usize) {
+ let size = core::mem::size_of::<T>();
+ let byte_len = min(src.len() * size, dest.len());
+ let num_chunks = (byte_len + size - 1) / size;
+
+ if cfg!(target_endian = "little") {
+ // On LE we can do a simple copy, which is 25-50% faster:
+ dest[..byte_len].copy_from_slice(&T::as_byte_slice(&src[..num_chunks])[..byte_len]);
+ } else {
+ // This code is valid on all arches, but slower than the above:
+ let mut i = 0;
+ let mut iter = dest[..byte_len].chunks_exact_mut(size);
+ for chunk in &mut iter {
+ chunk.copy_from_slice(src[i].to_le_bytes().as_ref());
+ i += 1;
+ }
+ let chunk = iter.into_remainder();
+ if !chunk.is_empty() {
+ chunk.copy_from_slice(&src[i].to_le_bytes().as_ref()[..chunk.len()]);
+ }
+ }
+
+ (num_chunks, byte_len)
+}
+
+/// Implement `fill_bytes` by reading chunks from the output buffer of a block
+/// based RNG.
+///
+/// The return values are `(consumed_u32, filled_u8)`.
+///
+/// `filled_u8` is the number of filled bytes in `dest`, which may be less than
+/// the length of `dest`.
+/// `consumed_u32` is the number of words consumed from `src`, which is the same
+/// as `filled_u8 / 4` rounded up.
+///
+/// # Example
+/// (from `IsaacRng`)
+///
+/// ```ignore
+/// fn fill_bytes(&mut self, dest: &mut [u8]) {
+/// let mut read_len = 0;
+/// while read_len < dest.len() {
+/// if self.index >= self.rsl.len() {
+/// self.isaac();
+/// }
+///
+/// let (consumed_u32, filled_u8) =
+/// impls::fill_via_u32_chunks(&mut self.rsl[self.index..],
+/// &mut dest[read_len..]);
+///
+/// self.index += consumed_u32;
+/// read_len += filled_u8;
+/// }
+/// }
+/// ```
+pub fn fill_via_u32_chunks(src: &[u32], dest: &mut [u8]) -> (usize, usize) {
+ fill_via_chunks(src, dest)
+}
+
+/// Implement `fill_bytes` by reading chunks from the output buffer of a block
+/// based RNG.
+///
+/// The return values are `(consumed_u64, filled_u8)`.
+/// `filled_u8` is the number of filled bytes in `dest`, which may be less than
+/// the length of `dest`.
+/// `consumed_u64` is the number of words consumed from `src`, which is the same
+/// as `filled_u8 / 8` rounded up.
+///
+/// See `fill_via_u32_chunks` for an example.
+pub fn fill_via_u64_chunks(src: &[u64], dest: &mut [u8]) -> (usize, usize) {
+ fill_via_chunks(src, dest)
+}
+
+/// Implement `next_u32` via `fill_bytes`, little-endian order.
+pub fn next_u32_via_fill<R: RngCore + ?Sized>(rng: &mut R) -> u32 {
+ let mut buf = [0; 4];
+ rng.fill_bytes(&mut buf);
+ u32::from_le_bytes(buf)
+}
+
+/// Implement `next_u64` via `fill_bytes`, little-endian order.
+pub fn next_u64_via_fill<R: RngCore + ?Sized>(rng: &mut R) -> u64 {
+ let mut buf = [0; 8];
+ rng.fill_bytes(&mut buf);
+ u64::from_le_bytes(buf)
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn test_fill_via_u32_chunks() {
+ let src = [1, 2, 3];
+ let mut dst = [0u8; 11];
+ assert_eq!(fill_via_u32_chunks(&src, &mut dst), (3, 11));
+ assert_eq!(dst, [1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0]);
+
+ let mut dst = [0u8; 13];
+ assert_eq!(fill_via_u32_chunks(&src, &mut dst), (3, 12));
+ assert_eq!(dst, [1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0]);
+
+ let mut dst = [0u8; 5];
+ assert_eq!(fill_via_u32_chunks(&src, &mut dst), (2, 5));
+ assert_eq!(dst, [1, 0, 0, 0, 2]);
+ }
+
+ #[test]
+ fn test_fill_via_u64_chunks() {
+ let src = [1, 2];
+ let mut dst = [0u8; 11];
+ assert_eq!(fill_via_u64_chunks(&src, &mut dst), (2, 11));
+ assert_eq!(dst, [1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0]);
+
+ let mut dst = [0u8; 17];
+ assert_eq!(fill_via_u64_chunks(&src, &mut dst), (2, 16));
+ assert_eq!(dst, [1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0]);
+
+ let mut dst = [0u8; 5];
+ assert_eq!(fill_via_u64_chunks(&src, &mut dst), (1, 5));
+ assert_eq!(dst, [1, 0, 0, 0, 0]);
+ }
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56
// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Little-Endian utilities
+//!
+//! Little-Endian order has been chosen for internal usage; this makes some
+//! useful functions available.
+
+use core::convert::TryInto;
+
+/// Reads unsigned 32 bit integers from `src` into `dst`.
+#[inline]
+pub fn read_u32_into(src: &[u8], dst: &mut [u32]) {
+ assert!(src.len() >= 4 * dst.len());
+ for (out, chunk) in dst.iter_mut().zip(src.chunks_exact(4)) {
+ *out = u32::from_le_bytes(chunk.try_into().unwrap());
+ }
+}
+
+/// Reads unsigned 64 bit integers from `src` into `dst`.
+#[inline]
+pub fn read_u64_into(src: &[u8], dst: &mut [u64]) {
+ assert!(src.len() >= 8 * dst.len());
+ for (out, chunk) in dst.iter_mut().zip(src.chunks_exact(8)) {
+ *out = u64::from_le_bytes(chunk.try_into().unwrap());
+ }
+}
+
+#[test]
+fn test_read() {
+ let bytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
+
+ let mut buf = [0u32; 4];
+ read_u32_into(&bytes, &mut buf);
+ assert_eq!(buf[0], 0x04030201);
+ assert_eq!(buf[3], 0x100F0E0D);
+
+ let mut buf = [0u32; 3];
+ read_u32_into(&bytes[1..13], &mut buf); // unaligned
+ assert_eq!(buf[0], 0x05040302);
+ assert_eq!(buf[2], 0x0D0C0B0A);
+
+ let mut buf = [0u64; 2];
+ read_u64_into(&bytes, &mut buf);
+ assert_eq!(buf[0], 0x0807060504030201);
+ assert_eq!(buf[1], 0x100F0E0D0C0B0A09);
+
+ let mut buf = [0u64; 1];
+ read_u64_into(&bytes[7..15], &mut buf); // unaligned
+ assert_eq!(buf[0], 0x0F0E0D0C0B0A0908);
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531
// Copyright 2018 Developers of the Rand project.
+// Copyright 2017-2018 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Random number generation traits
+//!
+//! This crate is mainly of interest to crates publishing implementations of
+//! [`RngCore`]. Other users are encouraged to use the [`rand`] crate instead
+//! which re-exports the main traits and error types.
+//!
+//! [`RngCore`] is the core trait implemented by algorithmic pseudo-random number
+//! generators and external random-number sources.
+//!
+//! [`SeedableRng`] is an extension trait for construction from fixed seeds and
+//! other random number generators.
+//!
+//! [`Error`] is provided for error-handling. It is safe to use in `no_std`
+//! environments.
+//!
+//! The [`impls`] and [`le`] sub-modules include a few small functions to assist
+//! implementation of [`RngCore`].
+//!
+//! [`rand`]: https://docs.rs/rand
+
+#![doc(
+ html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
+ html_favicon_url = "https://www.rust-lang.org/favicon.ico",
+ html_root_url = "https://rust-random.github.io/rand/"
+)]
+#![deny(missing_docs)]
+#![deny(missing_debug_implementations)]
+#![doc(test(attr(allow(unused_variables), deny(warnings))))]
+#![cfg_attr(doc_cfg, feature(doc_cfg))]
+#![no_std]
+
+use core::convert::AsMut;
+use core::default::Default;
+
+#[cfg(feature = "std")] extern crate std;
+#[cfg(feature = "alloc")] extern crate alloc;
+#[cfg(feature = "alloc")] use alloc::boxed::Box;
+
+pub use error::Error;
+#[cfg(feature = "getrandom")] pub use os::OsRng;
+
+
+pub mod block;
+mod error;
+pub mod impls;
+pub mod le;
+#[cfg(feature = "getrandom")] mod os;
+
+
+/// The core of a random number generator.
+///
+/// This trait encapsulates the low-level functionality common to all
+/// generators, and is the "back end", to be implemented by generators.
+/// End users should normally use the `Rng` trait from the [`rand`] crate,
+/// which is automatically implemented for every type implementing `RngCore`.
+///
+/// Three different methods for generating random data are provided since the
+/// optimal implementation of each is dependent on the type of generator. There
+/// is no required relationship between the output of each; e.g. many
+/// implementations of [`fill_bytes`] consume a whole number of `u32` or `u64`
+/// values and drop any remaining unused bytes. The same can happen with the
+/// [`next_u32`] and [`next_u64`] methods, implementations may discard some
+/// random bits for efficiency.
+///
+/// The [`try_fill_bytes`] method is a variant of [`fill_bytes`] allowing error
+/// handling; it is not deemed sufficiently useful to add equivalents for
+/// [`next_u32`] or [`next_u64`] since the latter methods are almost always used
+/// with algorithmic generators (PRNGs), which are normally infallible.
+///
+/// Implementers should produce bits uniformly. Pathological RNGs (e.g. always
+/// returning the same value, or never setting certain bits) can break rejection
+/// sampling used by random distributions, and also break other RNGs when
+/// seeding them via [`SeedableRng::from_rng`].
+///
+/// Algorithmic generators implementing [`SeedableRng`] should normally have
+/// *portable, reproducible* output, i.e. fix Endianness when converting values
+/// to avoid platform differences, and avoid making any changes which affect
+/// output (except by communicating that the release has breaking changes).
+///
+/// Typically an RNG will implement only one of the methods available
+/// in this trait directly, then use the helper functions from the
+/// [`impls`] module to implement the other methods.
+///
+/// It is recommended that implementations also implement:
+///
+/// - `Debug` with a custom implementation which *does not* print any internal
+/// state (at least, [`CryptoRng`]s should not risk leaking state through
+/// `Debug`).
+/// - `Serialize` and `Deserialize` (from Serde), preferably making Serde
+/// support optional at the crate level in PRNG libs.
+/// - `Clone`, if possible.
+/// - *never* implement `Copy` (accidental copies may cause repeated values).
+/// - *do not* implement `Default` for pseudorandom generators, but instead
+/// implement [`SeedableRng`], to guide users towards proper seeding.
+/// External / hardware RNGs can choose to implement `Default`.
+/// - `Eq` and `PartialEq` could be implemented, but are probably not useful.
+///
+/// # Example
+///
+/// A simple example, obviously not generating very *random* output:
+///
+/// ```
+/// #![allow(dead_code)]
+/// use rand_core::{RngCore, Error, impls};
+///
+/// struct CountingRng(u64);
+///
+/// impl RngCore for CountingRng {
+/// fn next_u32(&mut self) -> u32 {
+/// self.next_u64() as u32
+/// }
+///
+/// fn next_u64(&mut self) -> u64 {
+/// self.0 += 1;
+/// self.0
+/// }
+///
+/// fn fill_bytes(&mut self, dest: &mut [u8]) {
+/// impls::fill_bytes_via_next(self, dest)
+/// }
+///
+/// fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+/// Ok(self.fill_bytes(dest))
+/// }
+/// }
+/// ```
+///
+/// [`rand`]: https://docs.rs/rand
+/// [`try_fill_bytes`]: RngCore::try_fill_bytes
+/// [`fill_bytes`]: RngCore::fill_bytes
+/// [`next_u32`]: RngCore::next_u32
+/// [`next_u64`]: RngCore::next_u64
+pub trait RngCore {
+ /// Return the next random `u32`.
+ ///
+ /// RNGs must implement at least one method from this trait directly. In
+ /// the case this method is not implemented directly, it can be implemented
+ /// using `self.next_u64() as u32` or via [`impls::next_u32_via_fill`].
+ fn next_u32(&mut self) -> u32;
+
+ /// Return the next random `u64`.
+ ///
+ /// RNGs must implement at least one method from this trait directly. In
+ /// the case this method is not implemented directly, it can be implemented
+ /// via [`impls::next_u64_via_u32`] or via [`impls::next_u64_via_fill`].
+ fn next_u64(&mut self) -> u64;
+
+ /// Fill `dest` with random data.
+ ///
+ /// RNGs must implement at least one method from this trait directly. In
+ /// the case this method is not implemented directly, it can be implemented
+ /// via [`impls::fill_bytes_via_next`] or
+ /// via [`RngCore::try_fill_bytes`]; if this generator can
+ /// fail the implementation must choose how best to handle errors here
+ /// (e.g. panic with a descriptive message or log a warning and retry a few
+ /// times).
+ ///
+ /// This method should guarantee that `dest` is entirely filled
+ /// with new data, and may panic if this is impossible
+ /// (e.g. reading past the end of a file that is being used as the
+ /// source of randomness).
+ fn fill_bytes(&mut self, dest: &mut [u8]);
+
+ /// Fill `dest` entirely with random data.
+ ///
+ /// This is the only method which allows an RNG to report errors while
+ /// generating random data thus making this the primary method implemented
+ /// by external (true) RNGs (e.g. `OsRng`) which can fail. It may be used
+ /// directly to generate keys and to seed (infallible) PRNGs.
+ ///
+ /// Other than error handling, this method is identical to [`RngCore::fill_bytes`];
+ /// thus this may be implemented using `Ok(self.fill_bytes(dest))` or
+ /// `fill_bytes` may be implemented with
+ /// `self.try_fill_bytes(dest).unwrap()` or more specific error handling.
+ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>;
+}
+
+/// A marker trait used to indicate that an [`RngCore`] or [`BlockRngCore`]
+/// implementation is supposed to be cryptographically secure.
+///
+/// *Cryptographically secure generators*, also known as *CSPRNGs*, should
+/// satisfy an additional properties over other generators: given the first
+/// *k* bits of an algorithm's output
+/// sequence, it should not be possible using polynomial-time algorithms to
+/// predict the next bit with probability significantly greater than 50%.
+///
+/// Some generators may satisfy an additional property, however this is not
+/// required by this trait: if the CSPRNG's state is revealed, it should not be
+/// computationally-feasible to reconstruct output prior to this. Some other
+/// generators allow backwards-computation and are considered *reversible*.
+///
+/// Note that this trait is provided for guidance only and cannot guarantee
+/// suitability for cryptographic applications. In general it should only be
+/// implemented for well-reviewed code implementing well-regarded algorithms.
+///
+/// Note also that use of a `CryptoRng` does not protect against other
+/// weaknesses such as seeding from a weak entropy source or leaking state.
+///
+/// [`BlockRngCore`]: block::BlockRngCore
+pub trait CryptoRng {}
+
+/// An extension trait that is automatically implemented for any type
+/// implementing [`RngCore`] and [`CryptoRng`].
+///
+/// It may be used as a trait object, and supports upcasting to [`RngCore`] via
+/// the [`CryptoRngCore::as_rngcore`] method.
+///
+/// # Example
+///
+/// ```
+/// use rand_core::CryptoRngCore;
+///
+/// #[allow(unused)]
+/// fn make_token(rng: &mut dyn CryptoRngCore) -> [u8; 32] {
+/// let mut buf = [0u8; 32];
+/// rng.fill_bytes(&mut buf);
+/// buf
+/// }
+/// ```
+pub trait CryptoRngCore: CryptoRng + RngCore {
+ /// Upcast to an [`RngCore`] trait object.
+ fn as_rngcore(&mut self) -> &mut dyn RngCore;
+}
+
+impl<T: CryptoRng + RngCore> CryptoRngCore for T {
+ fn as_rngcore(&mut self) -> &mut dyn RngCore {
+ self
+ }
+}
+
+/// A random number generator that can be explicitly seeded.
+///
+/// This trait encapsulates the low-level functionality common to all
+/// pseudo-random number generators (PRNGs, or algorithmic generators).
+///
+/// [`rand`]: https://docs.rs/rand
+pub trait SeedableRng: Sized {
+ /// Seed type, which is restricted to types mutably-dereferenceable as `u8`
+ /// arrays (we recommend `[u8; N]` for some `N`).
+ ///
+ /// It is recommended to seed PRNGs with a seed of at least circa 100 bits,
+ /// which means an array of `[u8; 12]` or greater to avoid picking RNGs with
+ /// partially overlapping periods.
+ ///
+ /// For cryptographic RNG's a seed of 256 bits is recommended, `[u8; 32]`.
+ ///
+ ///
+ /// # Implementing `SeedableRng` for RNGs with large seeds
+ ///
+ /// Note that the required traits `core::default::Default` and
+ /// `core::convert::AsMut<u8>` are not implemented for large arrays
+ /// `[u8; N]` with `N` > 32. To be able to implement the traits required by
+ /// `SeedableRng` for RNGs with such large seeds, the newtype pattern can be
+ /// used:
+ ///
+ /// ```
+ /// use rand_core::SeedableRng;
+ ///
+ /// const N: usize = 64;
+ /// pub struct MyRngSeed(pub [u8; N]);
+ /// pub struct MyRng(MyRngSeed);
+ ///
+ /// impl Default for MyRngSeed {
+ /// fn default() -> MyRngSeed {
+ /// MyRngSeed([0; N])
+ /// }
+ /// }
+ ///
+ /// impl AsMut<[u8]> for MyRngSeed {
+ /// fn as_mut(&mut self) -> &mut [u8] {
+ /// &mut self.0
+ /// }
+ /// }
+ ///
+ /// impl SeedableRng for MyRng {
+ /// type Seed = MyRngSeed;
+ ///
+ /// fn from_seed(seed: MyRngSeed) -> MyRng {
+ /// MyRng(seed)
+ /// }
+ /// }
+ /// ```
+ type Seed: Sized + Default + AsMut<[u8]>;
+
+ /// Create a new PRNG using the given seed.
+ ///
+ /// PRNG implementations are allowed to assume that bits in the seed are
+ /// well distributed. That means usually that the number of one and zero
+ /// bits are roughly equal, and values like 0, 1 and (size - 1) are unlikely.
+ /// Note that many non-cryptographic PRNGs will show poor quality output
+ /// if this is not adhered to. If you wish to seed from simple numbers, use
+ /// `seed_from_u64` instead.
+ ///
+ /// All PRNG implementations should be reproducible unless otherwise noted:
+ /// given a fixed `seed`, the same sequence of output should be produced
+ /// on all runs, library versions and architectures (e.g. check endianness).
+ /// Any "value-breaking" changes to the generator should require bumping at
+ /// least the minor version and documentation of the change.
+ ///
+ /// It is not required that this function yield the same state as a
+ /// reference implementation of the PRNG given equivalent seed; if necessary
+ /// another constructor replicating behaviour from a reference
+ /// implementation can be added.
+ ///
+ /// PRNG implementations should make sure `from_seed` never panics. In the
+ /// case that some special values (like an all zero seed) are not viable
+ /// seeds it is preferable to map these to alternative constant value(s),
+ /// for example `0xBAD5EEDu32` or `0x0DDB1A5E5BAD5EEDu64` ("odd biases? bad
+ /// seed"). This is assuming only a small number of values must be rejected.
+ fn from_seed(seed: Self::Seed) -> Self;
+
+ /// Create a new PRNG using a `u64` seed.
+ ///
+ /// This is a convenience-wrapper around `from_seed` to allow construction
+ /// of any `SeedableRng` from a simple `u64` value. It is designed such that
+ /// low Hamming Weight numbers like 0 and 1 can be used and should still
+ /// result in good, independent seeds to the PRNG which is returned.
+ ///
+ /// This **is not suitable for cryptography**, as should be clear given that
+ /// the input size is only 64 bits.
+ ///
+ /// Implementations for PRNGs *may* provide their own implementations of
+ /// this function, but the default implementation should be good enough for
+ /// all purposes. *Changing* the implementation of this function should be
+ /// considered a value-breaking change.
+ fn seed_from_u64(mut state: u64) -> Self {
+ // We use PCG32 to generate a u32 sequence, and copy to the seed
+ fn pcg32(state: &mut u64) -> [u8; 4] {
+ const MUL: u64 = 6364136223846793005;
+ const INC: u64 = 11634580027462260723;
+
+ // We advance the state first (to get away from the input value,
+ // in case it has low Hamming Weight).
+ *state = state.wrapping_mul(MUL).wrapping_add(INC);
+ let state = *state;
+
+ // Use PCG output function with to_le to generate x:
+ let xorshifted = (((state >> 18) ^ state) >> 27) as u32;
+ let rot = (state >> 59) as u32;
+ let x = xorshifted.rotate_right(rot);
+ x.to_le_bytes()
+ }
+
+ let mut seed = Self::Seed::default();
+ let mut iter = seed.as_mut().chunks_exact_mut(4);
+ for chunk in &mut iter {
+ chunk.copy_from_slice(&pcg32(&mut state));
+ }
+ let rem = iter.into_remainder();
+ if !rem.is_empty() {
+ rem.copy_from_slice(&pcg32(&mut state)[..rem.len()]);
+ }
+
+ Self::from_seed(seed)
+ }
+
+ /// Create a new PRNG seeded from another `Rng`.
+ ///
+ /// This may be useful when needing to rapidly seed many PRNGs from a master
+ /// PRNG, and to allow forking of PRNGs. It may be considered deterministic.
+ ///
+ /// The master PRNG should be at least as high quality as the child PRNGs.
+ /// When seeding non-cryptographic child PRNGs, we recommend using a
+ /// different algorithm for the master PRNG (ideally a CSPRNG) to avoid
+ /// correlations between the child PRNGs. If this is not possible (e.g.
+ /// forking using small non-crypto PRNGs) ensure that your PRNG has a good
+ /// mixing function on the output or consider use of a hash function with
+ /// `from_seed`.
+ ///
+ /// Note that seeding `XorShiftRng` from another `XorShiftRng` provides an
+ /// extreme example of what can go wrong: the new PRNG will be a clone
+ /// of the parent.
+ ///
+ /// PRNG implementations are allowed to assume that a good RNG is provided
+ /// for seeding, and that it is cryptographically secure when appropriate.
+ /// As of `rand` 0.7 / `rand_core` 0.5, implementations overriding this
+ /// method should ensure the implementation satisfies reproducibility
+ /// (in prior versions this was not required).
+ ///
+ /// [`rand`]: https://docs.rs/rand
+ fn from_rng<R: RngCore>(mut rng: R) -> Result<Self, Error> {
+ let mut seed = Self::Seed::default();
+ rng.try_fill_bytes(seed.as_mut())?;
+ Ok(Self::from_seed(seed))
+ }
+
+ /// Creates a new instance of the RNG seeded via [`getrandom`].
+ ///
+ /// This method is the recommended way to construct non-deterministic PRNGs
+ /// since it is convenient and secure.
+ ///
+ /// In case the overhead of using [`getrandom`] to seed *many* PRNGs is an
+ /// issue, one may prefer to seed from a local PRNG, e.g.
+ /// `from_rng(thread_rng()).unwrap()`.
+ ///
+ /// # Panics
+ ///
+ /// If [`getrandom`] is unable to provide secure entropy this method will panic.
+ ///
+ /// [`getrandom`]: https://docs.rs/getrandom
+ #[cfg(feature = "getrandom")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "getrandom")))]
+ fn from_entropy() -> Self {
+ let mut seed = Self::Seed::default();
+ if let Err(err) = getrandom::getrandom(seed.as_mut()) {
+ panic!("from_entropy failed: {}", err);
+ }
+ Self::from_seed(seed)
+ }
+}
+
+// Implement `RngCore` for references to an `RngCore`.
+// Force inlining all functions, so that it is up to the `RngCore`
+// implementation and the optimizer to decide on inlining.
+impl<'a, R: RngCore + ?Sized> RngCore for &'a mut R {
+ #[inline(always)]
+ fn next_u32(&mut self) -> u32 {
+ (**self).next_u32()
+ }
+
+ #[inline(always)]
+ fn next_u64(&mut self) -> u64 {
+ (**self).next_u64()
+ }
+
+ #[inline(always)]
+ fn fill_bytes(&mut self, dest: &mut [u8]) {
+ (**self).fill_bytes(dest)
+ }
+
+ #[inline(always)]
+ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+ (**self).try_fill_bytes(dest)
+ }
+}
+
+// Implement `RngCore` for boxed references to an `RngCore`.
+// Force inlining all functions, so that it is up to the `RngCore`
+// implementation and the optimizer to decide on inlining.
+#[cfg(feature = "alloc")]
+impl<R: RngCore + ?Sized> RngCore for Box<R> {
+ #[inline(always)]
+ fn next_u32(&mut self) -> u32 {
+ (**self).next_u32()
+ }
+
+ #[inline(always)]
+ fn next_u64(&mut self) -> u64 {
+ (**self).next_u64()
+ }
+
+ #[inline(always)]
+ fn fill_bytes(&mut self, dest: &mut [u8]) {
+ (**self).fill_bytes(dest)
+ }
+
+ #[inline(always)]
+ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+ (**self).try_fill_bytes(dest)
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::io::Read for dyn RngCore {
+ fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
+ self.try_fill_bytes(buf)?;
+ Ok(buf.len())
+ }
+}
+
+// Implement `CryptoRng` for references to a `CryptoRng`.
+impl<'a, R: CryptoRng + ?Sized> CryptoRng for &'a mut R {}
+
+// Implement `CryptoRng` for boxed references to a `CryptoRng`.
+#[cfg(feature = "alloc")]
+impl<R: CryptoRng + ?Sized> CryptoRng for Box<R> {}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn test_seed_from_u64() {
+ struct SeedableNum(u64);
+ impl SeedableRng for SeedableNum {
+ type Seed = [u8; 8];
+
+ fn from_seed(seed: Self::Seed) -> Self {
+ let mut x = [0u64; 1];
+ le::read_u64_into(&seed, &mut x);
+ SeedableNum(x[0])
+ }
+ }
+
+ const N: usize = 8;
+ const SEEDS: [u64; N] = [0u64, 1, 2, 3, 4, 8, 16, -1i64 as u64];
+ let mut results = [0u64; N];
+ for (i, seed) in SEEDS.iter().enumerate() {
+ let SeedableNum(x) = SeedableNum::seed_from_u64(*seed);
+ results[i] = x;
+ }
+
+ for (i1, r1) in results.iter().enumerate() {
+ let weight = r1.count_ones();
+ // This is the binomial distribution B(64, 0.5), so chance of
+ // weight < 20 is binocdf(19, 64, 0.5) = 7.8e-4, and same for
+ // weight > 44.
+ assert!((20..=44).contains(&weight));
+
+ for (i2, r2) in results.iter().enumerate() {
+ if i1 == i2 {
+ continue;
+ }
+ let diff_weight = (r1 ^ r2).count_ones();
+ assert!(diff_weight >= 20);
+ }
+ }
+
+ // value-breakage test:
+ assert_eq!(results[0], 5029875928683246316);
+ }
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208
// src/lib.rs
+//
+// Copyright (c) 2015,2017 rust-mersenne-twister developers
+// Copyright (c) 2020 Ryan Lopopolo <rjl@hyperbo.la>
+//
+// Licensed under the Apache License, Version 2.0
+// <LICENSE-APACHE> or <http://www.apache.org/licenses/LICENSE-2.0> or the MIT
+// license <LICENSE-MIT> or <http://opensource.org/licenses/MIT>, at your
+// option. All files in the project carrying such notice may not be copied,
+// modified, or distributed except according to those terms.
+
+#![deny(clippy::all)]
+#![deny(clippy::pedantic)]
+#![deny(clippy::cargo)]
+#![allow(unknown_lints)]
+#![deny(missing_debug_implementations)]
+#![warn(missing_docs)]
+#![warn(rust_2018_idioms)]
+#![warn(trivial_casts, trivial_numeric_casts)]
+#![warn(unused_qualifications)]
+#![warn(variant_size_differences)]
+#![forbid(unsafe_code)]
+// Enable feature callouts in generated documentation:
+// https://doc.rust-lang.org/beta/unstable-book/language-features/doc-cfg.html
+//
+// This approach is borrowed from tokio.
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![cfg_attr(docsrs, feature(doc_alias))]
+
+//! Mersenne Twister random number generators.
+//!
+//! This is a native Rust implementation of a selection of Mersenne Twister
+//! generators. Mersenne Twister is not suitable for cryptographic use.
+//!
+//! This crate provides:
+//!
+//! - [`Mt19937GenRand32`], the original reference Mersenne Twister
+//! implementation known as `MT19937`. This is a good choice on both 32-bit
+//! and 64-bit CPUs (for 32-bit output).
+//! - [`Mt19937GenRand64`], the 64-bit variant of `MT19937` known as
+//! `MT19937-64`. This algorithm produces a different output stream than
+//! `MT19937` and produces 64-bit output. This is a good choice on 64-bit
+//! CPUs.
+//!
+//! Both of these RNGs use approximately 2.5 kilobytes of state.
+//! [`Mt19937GenRand32`] uses a 32-bit seed. [`Mt19937GenRand64`] uses a 64-bit
+//! seed. Both can be seeded from an iterator of seeds.
+//!
+//! Both RNGs implement a `recover` constructor which can reconstruct the RNG
+//! state from a sequence of output samples.
+//!
+//! # Usage
+//!
+//! You can seed a RNG and begin sampling it:
+//!
+//! ```
+//! # use rand_mt::Mt64;
+//! // Create the RNG.
+//! let mut rng = Mt64::new(0x1234_567_89ab_cdef_u64);
+//! // start grabbing randomness from rng...
+//! let mut buf = vec![0; 512];
+//! rng.fill_bytes(&mut buf);
+//! ```
+//!
+//! Or if you want to use the default (fixed) seeds that are specified in the
+//! reference implementations:
+//!
+//! ```
+//! # use rand_mt::Mt;
+//! let default = Mt::default();
+//! let mt = Mt::new_unseeded();
+//! assert_eq!(default, mt);
+//! ```
+//!
+//! # Crate Features
+//!
+//! `rand_mt` is `no_std` compatible. `rand_mt` has several optional features
+//! that are enabled by default:
+//!
+//! - **rand-traits** - Enables a dependency on [`rand_core`]. Activating this
+//! feature implements `RngCore` and `SeedableRng` on the RNGs in this crate.
+//! - **std** - Enables a dependency on the Rust Standard Library. Activating
+//! this feature enables [`std::error::Error`] impls on error types in this
+//! crate.
+//!
+//! Mersenne Twister requires approximately 2.5 kilobytes of internal state. To
+//! make the RNGs implemented in this crate practical to embed in other structs,
+//! you may wish to store the RNG in a [`Box`].
+//!
+#![cfg_attr(
+ not(feature = "std"),
+ doc = "[`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html"
+)]
+#![cfg_attr(feature = "std", doc = "[`Box`]: std::boxed::Box")]
+#![cfg_attr(
+ not(feature = "std"),
+ doc = "[`Box`]: https://doc.rust-lang.org/std/boxed/struct.Box.html"
+)]
+#![cfg_attr(
+ not(feature = "rand_core"),
+ doc = "[`rand_core`]: https://crates.io/crates/rand_core"
+)]
+//!
+
+#![doc(html_root_url = "https://docs.rs/rand_mt/4.2.2")]
+#![no_std]
+
+#[cfg(feature = "std")]
+extern crate std;
+
+use core::fmt;
+
+pub use crate::mt::Mt19937GenRand32;
+pub use crate::mt64::Mt19937GenRand64;
+
+mod mt;
+mod mt64;
+#[cfg(test)]
+mod vectors;
+
+/// A type alias for [`Mt19937GenRand32`], 32-bit Mersenne Twister.
+pub type Mt = Mt19937GenRand32;
+
+/// A type alias for [`Mt19937GenRand64`], 64-bit Mersenne Twister.
+pub type Mt64 = Mt19937GenRand64;
+
+/// Error returned from fallible Mersenne Twister recovery constructors.
+///
+/// When the `std` feature is enabled, this type implements `std::error::Error`.
+#[non_exhaustive]
+#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
+pub enum RecoverRngError {
+ /// Attempted to recover an RNG with too many samples.
+ ///
+ /// Recover constructors require an exact number of samples to ensure the
+ /// recovered RNG matches the state of the RNG that supplied all of the
+ /// samples.
+ TooFewSamples(usize),
+ /// Attempted to recover an RNG with too few samples.
+ ///
+ /// Too few samples leaves the internal state buffer partially
+ /// uninitialized.
+ ///
+ /// Recover constructors require an exact number of samples to ensure the
+ /// recovered RNG matches the state of the RNG that supplied all of the
+ /// samples.
+ TooManySamples(usize),
+}
+
+impl fmt::Display for RecoverRngError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Self::TooFewSamples(expected) => {
+ write!(f, "Too few samples given to recover: expected {}", expected)
+ }
+ Self::TooManySamples(expected) => write!(
+ f,
+ "Too many samples given to recover: expected {}",
+ expected
+ ),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for RecoverRngError {}
+
+#[cfg(test)]
+mod tests {
+ #[cfg(feature = "std")]
+ use super::RecoverRngError;
+
+ #[test]
+ #[cfg(feature = "std")]
+ fn error_display_is_not_empty() {
+ use core::fmt::Write as _;
+ use std::string::String;
+
+ let test_cases = [
+ RecoverRngError::TooFewSamples(0),
+ RecoverRngError::TooFewSamples(124),
+ RecoverRngError::TooManySamples(0),
+ RecoverRngError::TooManySamples(987),
+ ];
+ for tc in test_cases {
+ let mut buf = String::new();
+ write!(&mut buf, "{}", tc).unwrap();
+ assert!(!buf.is_empty());
+ }
+ }
+}
+
+// Ensure code blocks in `README.md` compile.
+//
+// This module and macro declaration should be kept at the end of the file, in
+// order to not interfere with code coverage.
+#[cfg(doctest)]
+macro_rules! readme {
+ ($x:expr) => {
+ #[doc = $x]
+ mod readme {}
+ };
+ () => {
+ readme!(include_str!("../README.md"));
+ };
+}
+#[cfg(doctest)]
+readme!();
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +653 +654 +655 +656 +657 +658 +659 +660 +661 +662 +663 +664 +665 +666 +667 +668 +669 +670 +671 +672 +673 +674 +675 +676 +677 +678 +679 +680 +681 +682 +683 +684 +685 +686 +687 +688 +689 +690 +691 +692 +693 +694 +695 +696 +697
// src/mt.rs
+//
+// Copyright (c) 2015,2017 rust-mersenne-twister developers
+// Copyright (c) 2020 Ryan Lopopolo <rjl@hyperbo.la>
+//
+// Licensed under the Apache License, Version 2.0
+// <LICENSE-APACHE> or <http://www.apache.org/licenses/LICENSE-2.0> or the MIT
+// license <LICENSE-MIT> or <http://opensource.org/licenses/MIT>, at your
+// option. All files in the project carrying such notice may not be copied,
+// modified, or distributed except according to those terms.
+
+use core::convert::TryFrom;
+use core::fmt;
+use core::mem::size_of;
+use core::num::Wrapping;
+
+use crate::RecoverRngError;
+
+#[cfg(feature = "rand-traits")]
+mod rand;
+
+const N: usize = 624;
+const M: usize = 397;
+const ONE: Wrapping<u32> = Wrapping(1);
+const MATRIX_A: Wrapping<u32> = Wrapping(0x9908_b0df);
+const UPPER_MASK: Wrapping<u32> = Wrapping(0x8000_0000);
+const LOWER_MASK: Wrapping<u32> = Wrapping(0x7fff_ffff);
+
+/// The 32-bit flavor of the Mersenne Twister pseudorandom number
+/// generator.
+///
+/// The official name of this RNG is `MT19937`. It natively outputs `u32`.
+///
+/// # Size
+///
+/// `Mt19937GenRand32` requires approximately 2.5 kilobytes of internal state.
+///
+/// You may wish to store an `Mt19937GenRand32` on the heap in a [`Box`] to make
+/// it easier to embed in another struct.
+///
+/// `Mt19937GenRand32` is also the same size as
+/// [`Mt19937GenRand64`](crate::Mt19937GenRand64).
+///
+/// ```
+/// # use core::mem;
+/// # use rand_mt::{Mt19937GenRand32, Mt19937GenRand64};
+/// assert_eq!(2504, mem::size_of::<Mt19937GenRand32>());
+/// assert_eq!(mem::size_of::<Mt19937GenRand64>(), mem::size_of::<Mt19937GenRand32>());
+/// ```
+#[cfg_attr(feature = "std", doc = "[`Box`]: std::boxed::Box")]
+#[cfg_attr(
+ not(feature = "std"),
+ doc = "[`Box`]: https://doc.rust-lang.org/std/boxed/struct.Box.html"
+)]
+#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
+#[allow(clippy::module_name_repetitions)]
+pub struct Mt19937GenRand32 {
+ idx: usize,
+ state: [Wrapping<u32>; N],
+}
+
+impl fmt::Debug for Mt19937GenRand32 {
+ #[inline]
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str("Mt19937GenRand32 {}")
+ }
+}
+
+impl Default for Mt19937GenRand32 {
+ /// Return a new `Mt19937GenRand32` with the default seed.
+ ///
+ /// Equivalent to calling [`Mt19937GenRand32::new_unseeded`].
+ #[inline]
+ fn default() -> Self {
+ Self::new_unseeded()
+ }
+}
+
+impl From<[u8; 4]> for Mt19937GenRand32 {
+ /// Construct a Mersenne Twister RNG from 4 bytes.
+ ///
+ /// The given bytes are treated as a little endian encoded `u32`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand32;
+ /// // Default MT seed
+ /// let seed = 5489_u32.to_le_bytes();
+ /// let mut mt = Mt19937GenRand32::from(seed);
+ /// assert_ne!(mt.next_u32(), mt.next_u32());
+ /// ```
+ ///
+ /// This constructor is equivalent to passing a little endian encoded `u32`.
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand32;
+ /// // Default MT seed
+ /// let seed = 5489_u32.to_le_bytes();
+ /// let mt1 = Mt19937GenRand32::from(seed);
+ /// let mt2 = Mt19937GenRand32::new(5489_u32);
+ /// assert_eq!(mt1, mt2);
+ /// ```
+ #[inline]
+ fn from(seed: [u8; 4]) -> Self {
+ Self::new(u32::from_le_bytes(seed))
+ }
+}
+
+impl From<u32> for Mt19937GenRand32 {
+ /// Construct a Mersenne Twister RNG from a `u32` seed.
+ ///
+ /// This function is equivalent to [`new`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand32;
+ /// // Default MT seed
+ /// let seed = 5489_u32;
+ /// let mt1 = Mt19937GenRand32::from(seed);
+ /// let mt2 = Mt19937GenRand32::new(seed);
+ /// assert_eq!(mt1, mt2);
+ ///
+ /// // Non-default MT seed
+ /// let seed = 9927_u32;
+ /// let mt1 = Mt19937GenRand32::from(seed);
+ /// let mt2 = Mt19937GenRand32::new(seed);
+ /// assert_eq!(mt1, mt2);
+ /// ```
+ ///
+ /// [`new`]: Self::new
+ #[inline]
+ fn from(seed: u32) -> Self {
+ Self::new(seed)
+ }
+}
+
+impl From<[u32; N]> for Mt19937GenRand32 {
+ /// Recover the internal state of a Mersenne Twister using the past 624
+ /// samples.
+ ///
+ /// This conversion takes a history of samples from a RNG and returns a
+ /// RNG that will produce identical output to the RNG that supplied the
+ /// samples.
+ #[inline]
+ fn from(key: [u32; N]) -> Self {
+ let mut mt = Self {
+ idx: N,
+ state: [Wrapping(0); N],
+ };
+ for (sample, out) in key.iter().copied().zip(mt.state.iter_mut()) {
+ *out = Wrapping(untemper(sample));
+ }
+ mt
+ }
+}
+
+impl TryFrom<&[u32]> for Mt19937GenRand32 {
+ type Error = RecoverRngError;
+
+ /// Attempt to recover the internal state of a Mersenne Twister using the
+ /// past 624 samples.
+ ///
+ /// This conversion takes a history of samples from a RNG and returns a
+ /// RNG that will produce identical output to the RNG that supplied the
+ /// samples.
+ ///
+ /// This conversion is implemented with [`Mt19937GenRand32::recover`].
+ ///
+ /// # Errors
+ ///
+ /// If `key` has less than 624 elements, an error is returned because there
+ /// is not enough data to fully initialize the RNG.
+ ///
+ /// If `key` has more than 624 elements, an error is returned because the
+ /// recovered RNG will not produce identical output to the RNG that supplied
+ /// the samples.
+ #[inline]
+ fn try_from(key: &[u32]) -> Result<Self, Self::Error> {
+ Self::recover(key.iter().copied())
+ }
+}
+
+impl Mt19937GenRand32 {
+ /// Default seed used by [`Mt19937GenRand32::new_unseeded`].
+ pub const DEFAULT_SEED: u32 = 5489_u32;
+
+ /// Create a new Mersenne Twister random number generator using the given
+ /// seed.
+ ///
+ /// # Examples
+ ///
+ /// ## Constructing with a `u32` seed
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand32;
+ /// let seed = 123_456_789_u32;
+ /// let mt1 = Mt19937GenRand32::new(seed);
+ /// let mt2 = Mt19937GenRand32::from(seed.to_le_bytes());
+ /// assert_eq!(mt1, mt2);
+ /// ```
+ ///
+ /// ## Constructing with default seed
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand32;
+ /// let mt1 = Mt19937GenRand32::new(Mt19937GenRand32::DEFAULT_SEED);
+ /// let mt2 = Mt19937GenRand32::new_unseeded();
+ /// assert_eq!(mt1, mt2);
+ /// ```
+ #[inline]
+ #[must_use]
+ pub fn new(seed: u32) -> Self {
+ let mut mt = Self {
+ idx: 0,
+ state: [Wrapping(0); N],
+ };
+ mt.reseed(seed);
+ mt
+ }
+
+ /// Create a new Mersenne Twister random number generator using the given
+ /// key.
+ ///
+ /// Key can have any length.
+ #[inline]
+ #[must_use]
+ pub fn new_with_key<I>(key: I) -> Self
+ where
+ I: IntoIterator<Item = u32>,
+ I::IntoIter: Clone,
+ {
+ let mut mt = Self {
+ idx: 0,
+ state: [Wrapping(0); N],
+ };
+ mt.reseed_with_key(key);
+ mt
+ }
+
+ /// Create a new Mersenne Twister random number generator using the default
+ /// fixed seed.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand32;
+ /// // Default MT seed
+ /// let seed = 5489_u32;
+ /// let mt = Mt19937GenRand32::new(seed);
+ /// let unseeded = Mt19937GenRand32::new_unseeded();
+ /// assert_eq!(mt, unseeded);
+ /// ```
+ #[inline]
+ #[must_use]
+ pub fn new_unseeded() -> Self {
+ Self::new(Self::DEFAULT_SEED)
+ }
+
+ /// Generate next `u64` output.
+ ///
+ /// This function is implemented by generating two `u32`s from the RNG and
+ /// performing shifting and masking to turn them into a `u64` output.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand32;
+ /// let mut mt = Mt19937GenRand32::new_unseeded();
+ /// assert_ne!(mt.next_u64(), mt.next_u64());
+ /// ```
+ #[inline]
+ pub fn next_u64(&mut self) -> u64 {
+ let out = u64::from(self.next_u32());
+ let out = out << 32;
+ out | u64::from(self.next_u32())
+ }
+
+ /// Generate next `u32` output.
+ ///
+ /// `u32` is the native output of the generator. This function advances the
+ /// RNG step counter by one.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand32;
+ /// let mut mt = Mt19937GenRand32::new_unseeded();
+ /// assert_ne!(mt.next_u32(), mt.next_u32());
+ /// ```
+ #[inline]
+ pub fn next_u32(&mut self) -> u32 {
+ // Failing this check indicates that, somehow, the structure
+ // was not initialized.
+ debug_assert!(self.idx != 0);
+ if self.idx >= N {
+ fill_next_state(self);
+ }
+ let Wrapping(x) = self.state[self.idx];
+ self.idx += 1;
+ temper(x)
+ }
+
+ /// Fill a buffer with bytes generated from the RNG.
+ ///
+ /// This method generates random `u32`s (the native output unit of the RNG)
+ /// until `dest` is filled.
+ ///
+ /// This method may discard some output bits if `dest.len()` is not a
+ /// multiple of 4.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand32;
+ /// let mut mt = Mt19937GenRand32::new_unseeded();
+ /// let mut buf = [0; 32];
+ /// mt.fill_bytes(&mut buf);
+ /// assert_ne!([0; 32], buf);
+ /// let mut buf = [0; 31];
+ /// mt.fill_bytes(&mut buf);
+ /// assert_ne!([0; 31], buf);
+ /// ```
+ #[inline]
+ pub fn fill_bytes(&mut self, dest: &mut [u8]) {
+ const CHUNK: usize = size_of::<u32>();
+ let mut dest_chunks = dest.chunks_exact_mut(CHUNK);
+
+ for next in &mut dest_chunks {
+ let chunk: [u8; CHUNK] = self.next_u32().to_le_bytes();
+ next.copy_from_slice(&chunk);
+ }
+
+ let remainder = dest_chunks.into_remainder();
+ if remainder.is_empty() {
+ return;
+ }
+ remainder
+ .iter_mut()
+ .zip(self.next_u32().to_le_bytes().iter())
+ .for_each(|(cell, &byte)| {
+ *cell = byte;
+ });
+ }
+
+ /// Attempt to recover the internal state of a Mersenne Twister using the
+ /// past 624 samples.
+ ///
+ /// This conversion takes a history of samples from a RNG and returns a
+ /// RNG that will produce identical output to the RNG that supplied the
+ /// samples.
+ ///
+ /// This constructor is also available as a [`TryFrom`] implementation for
+ /// `&[u32]`.
+ ///
+ /// # Errors
+ ///
+ /// If `key` has less than 624 elements, an error is returned because there
+ /// is not enough data to fully initialize the RNG.
+ ///
+ /// If `key` has more than 624 elements, an error is returned because the
+ /// recovered RNG will not produce identical output to the RNG that supplied
+ /// the samples.
+ #[inline]
+ pub fn recover<I>(key: I) -> Result<Self, RecoverRngError>
+ where
+ I: IntoIterator<Item = u32>,
+ {
+ let mut mt = Self {
+ idx: N,
+ state: [Wrapping(0); N],
+ };
+ let mut state = mt.state.iter_mut();
+ for sample in key {
+ let out = state.next().ok_or(RecoverRngError::TooManySamples(N))?;
+ *out = Wrapping(untemper(sample));
+ }
+ // If the state iterator still has unfilled cells, the given iterator
+ // was too short. If there are no additional cells, return the
+ // initialized RNG.
+ if state.next().is_none() {
+ Ok(mt)
+ } else {
+ Err(RecoverRngError::TooFewSamples(N))
+ }
+ }
+
+ /// Reseed a Mersenne Twister from a single `u32`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand32;
+ /// // Default MT seed
+ /// let mut mt = Mt19937GenRand32::new_unseeded();
+ /// let first = mt.next_u32();
+ /// mt.fill_bytes(&mut [0; 512]);
+ /// // Default MT seed
+ /// mt.reseed(5489_u32);
+ /// assert_eq!(first, mt.next_u32());
+ /// ```
+ #[inline]
+ #[allow(clippy::cast_possible_truncation)]
+ pub fn reseed(&mut self, seed: u32) {
+ self.idx = N;
+ self.state[0] = Wrapping(seed);
+ for i in 1..N {
+ self.state[i] = Wrapping(1_812_433_253)
+ * (self.state[i - 1] ^ (self.state[i - 1] >> 30))
+ + Wrapping(i as u32);
+ }
+ }
+
+ /// Reseed a Mersenne Twister from am iterator of `u32`s.
+ ///
+ /// Key can have any length.
+ #[inline]
+ #[allow(clippy::cast_possible_truncation)]
+ pub fn reseed_with_key<I>(&mut self, key: I)
+ where
+ I: IntoIterator<Item = u32>,
+ I::IntoIter: Clone,
+ {
+ self.reseed(19_650_218_u32);
+ let mut i = 1_usize;
+ for (j, piece) in key.into_iter().enumerate().cycle().take(N) {
+ self.state[i] = (self.state[i]
+ ^ ((self.state[i - 1] ^ (self.state[i - 1] >> 30)) * Wrapping(1_664_525)))
+ + Wrapping(piece)
+ + Wrapping(j as u32);
+ i += 1;
+ if i >= N {
+ self.state[0] = self.state[N - 1];
+ i = 1;
+ }
+ }
+ for _ in 0..N - 1 {
+ self.state[i] = (self.state[i]
+ ^ ((self.state[i - 1] ^ (self.state[i - 1] >> 30)) * Wrapping(1_566_083_941)))
+ - Wrapping(i as u32);
+ i += 1;
+ if i >= N {
+ self.state[0] = self.state[N - 1];
+ i = 1;
+ }
+ }
+ self.state[0] = Wrapping(1 << 31);
+ }
+}
+
+#[inline]
+fn temper(mut x: u32) -> u32 {
+ x ^= x >> 11;
+ x ^= (x << 7) & 0x9d2c_5680;
+ x ^= (x << 15) & 0xefc6_0000;
+ x ^= x >> 18;
+ x
+}
+
+#[inline]
+fn untemper(mut x: u32) -> u32 {
+ // reverse `x ^= x>>18;`
+ x ^= x >> 18;
+
+ // reverse `x ^= (x<<15) & 0xefc6_0000;`
+ x ^= (x << 15) & 0x2fc6_0000;
+ x ^= (x << 15) & 0xc000_0000;
+
+ // reverse `x ^= (x<< 7) & 0x9d2c_5680;`
+ x ^= (x << 7) & 0x0000_1680;
+ x ^= (x << 7) & 0x000c_4000;
+ x ^= (x << 7) & 0x0d20_0000;
+ x ^= (x << 7) & 0x9000_0000;
+
+ // reverse `x ^= x>>11;`
+ x ^= x >> 11;
+ x ^= x >> 22;
+
+ x
+}
+
+#[inline]
+fn fill_next_state(rng: &mut Mt19937GenRand32) {
+ for i in 0..N - M {
+ let x = (rng.state[i] & UPPER_MASK) | (rng.state[i + 1] & LOWER_MASK);
+ rng.state[i] = rng.state[i + M] ^ (x >> 1) ^ ((x & ONE) * MATRIX_A);
+ }
+ for i in N - M..N - 1 {
+ let x = (rng.state[i] & UPPER_MASK) | (rng.state[i + 1] & LOWER_MASK);
+ rng.state[i] = rng.state[i + M - N] ^ (x >> 1) ^ ((x & ONE) * MATRIX_A);
+ }
+ let x = (rng.state[N - 1] & UPPER_MASK) | (rng.state[0] & LOWER_MASK);
+ rng.state[N - 1] = rng.state[M - 1] ^ (x >> 1) ^ ((x & ONE) * MATRIX_A);
+ rng.idx = 0;
+}
+
+#[cfg(test)]
+mod tests {
+ use core::convert::TryFrom;
+ use core::iter;
+ use core::num::Wrapping;
+
+ use super::{Mt19937GenRand32, N};
+ use crate::vectors::mt::{STATE_SEEDED_BY_SLICE, STATE_SEEDED_BY_U32, TEST_OUTPUT};
+ use crate::RecoverRngError;
+
+ #[test]
+ fn seeded_state_from_u32_seed() {
+ let mt = Mt19937GenRand32::new(0x1234_5678_u32);
+ let mt_from_seed = Mt19937GenRand32::from(0x1234_5678_u32.to_le_bytes());
+ assert_eq!(mt.state, mt_from_seed.state);
+ for (&Wrapping(x), &y) in mt.state.iter().zip(STATE_SEEDED_BY_U32.iter()) {
+ assert_eq!(x, y);
+ }
+ for (&Wrapping(x), &y) in mt_from_seed.state.iter().zip(STATE_SEEDED_BY_U32.iter()) {
+ assert_eq!(x, y);
+ }
+ }
+
+ #[test]
+ fn seeded_state_from_u32_slice_key() {
+ let key = [0x123_u32, 0x234_u32, 0x345_u32, 0x456_u32];
+ let mt = Mt19937GenRand32::new_with_key(key.iter().copied());
+ for (&Wrapping(x), &y) in mt.state.iter().zip(STATE_SEEDED_BY_SLICE.iter()) {
+ assert_eq!(x, y);
+ }
+ }
+
+ #[test]
+ fn seed_with_empty_iter_returns() {
+ let _rng = Mt19937GenRand32::new_with_key(iter::empty());
+ }
+
+ #[test]
+ fn output_from_u32_slice_key() {
+ let key = [0x123_u32, 0x234_u32, 0x345_u32, 0x456_u32];
+ let mut mt = Mt19937GenRand32::new_with_key(key.iter().copied());
+ for &x in &TEST_OUTPUT {
+ assert_eq!(x, mt.next_u32());
+ }
+ }
+
+ #[test]
+ fn temper_untemper_is_identity() {
+ let mut buf = [0; 4];
+ for _ in 0..10_000 {
+ getrandom::getrandom(&mut buf).unwrap();
+ let x = u32::from_le_bytes(buf);
+ assert_eq!(x, super::untemper(super::temper(x)));
+ let x = u32::from_be_bytes(buf);
+ assert_eq!(x, super::untemper(super::temper(x)));
+ }
+ }
+
+ #[test]
+ fn untemper_temper_is_identity() {
+ let mut buf = [0; 4];
+ for _ in 0..10_000 {
+ getrandom::getrandom(&mut buf).unwrap();
+ let x = u32::from_le_bytes(buf);
+ assert_eq!(x, super::temper(super::untemper(x)));
+ let x = u32::from_be_bytes(buf);
+ assert_eq!(x, super::temper(super::untemper(x)));
+ }
+ }
+
+ #[test]
+ fn recovery_via_from() {
+ let mut buf = [0; 4];
+ for _ in 0..100 {
+ getrandom::getrandom(&mut buf).unwrap();
+ let seed = u32::from_le_bytes(buf);
+ for skip in 0..256 {
+ let mut orig_mt = Mt19937GenRand32::new(seed);
+ // skip some samples so the RNG is in an intermediate state
+ for _ in 0..skip {
+ orig_mt.next_u32();
+ }
+ let mut samples = [0; 624];
+ for sample in &mut samples {
+ *sample = orig_mt.next_u32();
+ }
+ let mut recovered_mt = Mt19937GenRand32::from(samples);
+ for _ in 0..624 * 2 {
+ assert_eq!(orig_mt.next_u32(), recovered_mt.next_u32());
+ }
+ }
+ }
+ }
+
+ #[test]
+ fn recovery_via_recover() {
+ let mut buf = [0; 4];
+ for _ in 0..100 {
+ getrandom::getrandom(&mut buf).unwrap();
+ let seed = u32::from_le_bytes(buf);
+ for skip in 0..256 {
+ let mut orig_mt = Mt19937GenRand32::new(seed);
+ // skip some samples so the RNG is in an intermediate state
+ for _ in 0..skip {
+ orig_mt.next_u32();
+ }
+ let mut samples = [0; 624];
+ for sample in &mut samples {
+ *sample = orig_mt.next_u32();
+ }
+ let mut recovered_mt = Mt19937GenRand32::recover(samples.iter().copied()).unwrap();
+ for _ in 0..624 * 2 {
+ assert_eq!(orig_mt.next_u32(), recovered_mt.next_u32());
+ }
+ }
+ }
+ }
+
+ #[test]
+ fn recover_required_exact_sample_length_via_from() {
+ assert_eq!(
+ Mt19937GenRand32::try_from(&[0; 0][..]),
+ Err(RecoverRngError::TooFewSamples(N))
+ );
+ assert_eq!(
+ Mt19937GenRand32::try_from(&[0; 1][..]),
+ Err(RecoverRngError::TooFewSamples(N))
+ );
+ assert_eq!(
+ Mt19937GenRand32::try_from(&[0; 623][..]),
+ Err(RecoverRngError::TooFewSamples(N))
+ );
+ Mt19937GenRand32::try_from(&[0; 624][..]).unwrap();
+ assert_eq!(
+ Mt19937GenRand32::try_from(&[0; 625][..]),
+ Err(RecoverRngError::TooManySamples(N))
+ );
+ assert_eq!(
+ Mt19937GenRand32::try_from(&[0; 1000][..]),
+ Err(RecoverRngError::TooManySamples(N))
+ );
+ }
+
+ #[test]
+ fn recover_required_exact_sample_length_via_recover() {
+ assert_eq!(
+ Mt19937GenRand32::recover([0; 0].iter().copied()),
+ Err(RecoverRngError::TooFewSamples(N))
+ );
+ assert_eq!(
+ Mt19937GenRand32::recover([0; 1].iter().copied()),
+ Err(RecoverRngError::TooFewSamples(N))
+ );
+ assert_eq!(
+ Mt19937GenRand32::recover([0; 623].iter().copied()),
+ Err(RecoverRngError::TooFewSamples(N))
+ );
+ Mt19937GenRand32::recover([0; 624].iter().copied()).unwrap();
+ assert_eq!(
+ Mt19937GenRand32::recover([0; 625].iter().copied()),
+ Err(RecoverRngError::TooManySamples(N))
+ );
+ assert_eq!(
+ Mt19937GenRand32::recover([0; 1000].iter().copied()),
+ Err(RecoverRngError::TooManySamples(N))
+ );
+ }
+
+ #[test]
+ #[cfg(feature = "std")]
+ fn fmt_debug_does_not_leak_seed() {
+ use core::fmt::Write as _;
+ use std::string::String;
+
+ let random = Mt19937GenRand32::new(874);
+
+ let mut buf = String::new();
+ write!(&mut buf, "{:?}", random).unwrap();
+ assert!(!buf.contains("874"));
+ assert_eq!(buf, "Mt19937GenRand32 {}");
+
+ let random = Mt19937GenRand32::new(123_456);
+
+ let mut buf = String::new();
+ write!(&mut buf, "{:?}", random).unwrap();
+ assert!(!buf.contains("123456"));
+ assert_eq!(buf, "Mt19937GenRand32 {}");
+ }
+
+ #[test]
+ fn default_is_new_unseeded() {
+ let mut default = Mt19937GenRand32::default();
+ let mut unseeded = Mt19937GenRand32::new_unseeded();
+
+ assert_eq!(default, unseeded);
+ for _ in 0..1024 {
+ assert_eq!(default.next_u32(), unseeded.next_u32());
+ }
+ }
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181
// src/mt/rand.rs
+//
+// Copyright (c) 2015,2017 rust-mersenne-twister developers
+// Copyright (c) 2020 Ryan Lopopolo <rjl@hyperbo.la>
+//
+// Licensed under the Apache License, Version 2.0
+// <LICENSE-APACHE> or <http://www.apache.org/licenses/LICENSE-2.0> or the MIT
+// license <LICENSE-MIT> or <http://opensource.org/licenses/MIT>, at your
+// option. All files in the project carrying such notice may not be copied,
+// modified, or distributed except according to those terms.
+
+use rand_core::{Error, RngCore, SeedableRng};
+
+use super::Mt19937GenRand32;
+
+impl SeedableRng for Mt19937GenRand32 {
+ type Seed = [u8; 4];
+
+ /// Reseed from a little endian encoded `u32`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rand_core::{RngCore, SeedableRng};
+ /// use rand_mt::Mt19937GenRand32;
+ ///
+ /// // Default MT seed
+ /// let seed = 5489_u32.to_le_bytes();
+ /// let mut rng = Mt19937GenRand32::from_seed(seed);
+ /// # fn example<T: RngCore>(mut rng: T) {
+ /// assert_ne!(rng.next_u32(), rng.next_u32());
+ /// # }
+ /// # example(rng);
+ /// ```
+ #[inline]
+ fn from_seed(seed: Self::Seed) -> Self {
+ Self::from(seed)
+ }
+}
+
+impl RngCore for Mt19937GenRand32 {
+ /// Generate next `u64` output.
+ ///
+ /// This function is implemented by generating two `u32`s from the RNG and
+ /// performing shifting and masking to turn them into a `u64` output.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rand_core::RngCore;
+ /// use rand_mt::Mt19937GenRand32;
+ ///
+ /// let mut rng = Mt19937GenRand32::new_unseeded();
+ /// # fn example<T: RngCore>(mut rng: T) {
+ /// assert_ne!(rng.next_u64(), rng.next_u64());
+ /// # }
+ /// # example(rng);
+ /// ```
+ #[inline]
+ fn next_u64(&mut self) -> u64 {
+ Self::next_u64(self)
+ }
+
+ /// Generate next `u32` output.
+ ///
+ /// `u32` is the native output of the generator. This function advances the
+ /// RNG step counter by one.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rand_core::RngCore;
+ /// use rand_mt::Mt19937GenRand32;
+ ///
+ /// let mut rng = Mt19937GenRand32::new_unseeded();
+ /// # fn example<T: RngCore>(mut rng: T) {
+ /// assert_ne!(rng.next_u32(), rng.next_u32());
+ /// # }
+ /// # example(rng);
+ /// ```
+ #[inline]
+ fn next_u32(&mut self) -> u32 {
+ Self::next_u32(self)
+ }
+
+ /// Fill a buffer with bytes generated from the RNG.
+ ///
+ /// This method generates random `u32`s (the native output unit of the RNG)
+ /// until `dest` is filled.
+ ///
+ /// This method may discard some output bits if `dest.len()` is not a
+ /// multiple of 4.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rand_core::RngCore;
+ /// use rand_mt::Mt19937GenRand32;
+ ///
+ /// let mut rng = Mt19937GenRand32::new_unseeded();
+ /// # fn example<T: RngCore>(mut rng: T) {
+ /// let mut buf = [0; 32];
+ /// rng.fill_bytes(&mut buf);
+ /// assert_ne!([0; 32], buf);
+ /// let mut buf = [0; 31];
+ /// rng.fill_bytes(&mut buf);
+ /// assert_ne!([0; 31], buf);
+ /// # }
+ /// # example(rng);
+ /// ```
+ #[inline]
+ fn fill_bytes(&mut self, dest: &mut [u8]) {
+ Self::fill_bytes(self, dest);
+ }
+
+ /// Fill a buffer with bytes generated from the RNG.
+ ///
+ /// This method generates random `u32`s (the native output unit of the RNG)
+ /// until `dest` is filled.
+ ///
+ /// This method may discard some output bits if `dest.len()` is not a
+ /// multiple of 4.
+ ///
+ /// `try_fill_bytes` is implemented with [`fill_bytes`](RngCore::fill_bytes)
+ /// and is infallible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rand_core::RngCore;
+ /// use rand_mt::Mt19937GenRand32;
+ ///
+ /// let mut rng = Mt19937GenRand32::new_unseeded();
+ /// # fn example<T: RngCore>(mut rng: T) -> Result<(), rand_core::Error> {
+ /// let mut buf = [0; 32];
+ /// rng.try_fill_bytes(&mut buf)?;
+ /// assert_ne!([0; 32], buf);
+ /// let mut buf = [0; 31];
+ /// rng.try_fill_bytes(&mut buf)?;
+ /// assert_ne!([0; 31], buf);
+ /// # Ok(())
+ /// # }
+ /// # example(rng).unwrap()
+ /// ```
+ #[inline]
+ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+ Self::fill_bytes(self, dest);
+ Ok(())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use core::num::Wrapping;
+ use rand_core::{RngCore, SeedableRng};
+
+ use super::Mt19937GenRand32;
+ use crate::vectors::mt::{STATE_SEEDED_BY_U32, TEST_OUTPUT};
+
+ #[test]
+ fn seeded_state_from_u32_seed() {
+ let rng = Mt19937GenRand32::new(0x1234_5678_u32);
+ let rng_from_seed = Mt19937GenRand32::from_seed(0x1234_5678_u32.to_le_bytes());
+ assert_eq!(rng.state, rng_from_seed.state);
+ for (&Wrapping(x), &y) in rng.state.iter().zip(STATE_SEEDED_BY_U32.iter()) {
+ assert_eq!(x, y);
+ }
+ for (&Wrapping(x), &y) in rng_from_seed.state.iter().zip(STATE_SEEDED_BY_U32.iter()) {
+ assert_eq!(x, y);
+ }
+ }
+
+ #[test]
+ fn output_from_u32_slice_key() {
+ let key = [0x123_u32, 0x234_u32, 0x345_u32, 0x456_u32];
+ let mut rng = Mt19937GenRand32::new_with_key(key.iter().copied());
+ for &x in &TEST_OUTPUT {
+ assert_eq!(x, RngCore::next_u32(&mut rng));
+ }
+ }
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +653 +654 +655 +656 +657 +658 +659 +660 +661 +662 +663 +664 +665 +666 +667 +668 +669 +670 +671 +672 +673 +674 +675 +676 +677 +678
// src/mt64.rs
+//
+// Copyright (c) 2015,2017 rust-mersenne-twister developers
+// Copyright (c) 2020 Ryan Lopopolo <rjl@hyperbo.la>
+//
+// Licensed under the Apache License, Version 2.0
+// <LICENSE-APACHE> or <http://www.apache.org/licenses/LICENSE-2.0> or the MIT
+// license <LICENSE-MIT> or <http://opensource.org/licenses/MIT>, at your
+// option. All files in the project carrying such notice may not be copied,
+// modified, or distributed except according to those terms.
+
+use core::convert::TryFrom;
+use core::fmt;
+use core::mem::size_of;
+use core::num::Wrapping;
+
+use crate::RecoverRngError;
+
+#[cfg(feature = "rand-traits")]
+mod rand;
+
+const NN: usize = 312;
+const MM: usize = 156;
+const ONE: Wrapping<u64> = Wrapping(1);
+const MATRIX_A: Wrapping<u64> = Wrapping(0xb502_6f5a_a966_19e9);
+const UM: Wrapping<u64> = Wrapping(0xffff_ffff_8000_0000); // Most significant 33 bits
+const LM: Wrapping<u64> = Wrapping(0x7fff_ffff); // Least significant 31 bits
+
+/// The 64-bit flavor of the Mersenne Twister pseudorandom number
+/// generator.
+///
+/// # Size
+///
+/// `Mt19937GenRand64` requires approximately 2.5 kilobytes of internal state.
+///
+/// You may wish to store an `Mt19937GenRand64` on the heap in a [`Box`] to make it
+/// easier to embed in another struct.
+///
+/// `Mt19937GenRand64` is also the same size as
+/// [`Mt19937GenRand32`](crate::Mt19937GenRand32).
+///
+/// ```
+/// # use core::mem;
+/// # use rand_mt::{Mt19937GenRand32, Mt19937GenRand64};
+/// assert_eq!(2504, mem::size_of::<Mt19937GenRand64>());
+/// assert_eq!(mem::size_of::<Mt19937GenRand32>(), mem::size_of::<Mt19937GenRand64>());
+/// ```
+#[cfg_attr(feature = "std", doc = "[`Box`]: std::boxed::Box")]
+#[cfg_attr(
+ not(feature = "std"),
+ doc = "[`Box`]: https://doc.rust-lang.org/std/boxed/struct.Box.html"
+)]
+#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Mt19937GenRand64 {
+ idx: usize,
+ state: [Wrapping<u64>; NN],
+}
+
+impl fmt::Debug for Mt19937GenRand64 {
+ #[inline]
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str("Mt19937GenRand64 {}")
+ }
+}
+
+impl Default for Mt19937GenRand64 {
+ /// Return a new `Mt19937GenRand64` with the default seed.
+ ///
+ /// Equivalent to calling [`Mt19937GenRand64::new_unseeded`].
+ #[inline]
+ fn default() -> Self {
+ Self::new_unseeded()
+ }
+}
+
+impl From<[u8; 8]> for Mt19937GenRand64 {
+ /// Construct a Mersenne Twister RNG from 8 bytes.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand64;
+ /// // Default MT seed
+ /// let seed = 5489_u64.to_le_bytes();
+ /// let mut mt = Mt19937GenRand64::from(seed);
+ /// assert_ne!(mt.next_u64(), mt.next_u64());
+ /// ```
+ #[inline]
+ fn from(seed: [u8; 8]) -> Self {
+ Self::new(u64::from_le_bytes(seed))
+ }
+}
+
+impl From<u64> for Mt19937GenRand64 {
+ /// Construct a Mersenne Twister RNG from a `u64` seed.
+ ///
+ /// This function is equivalent to [`new`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand64;
+ /// // Default MT seed
+ /// let seed = 5489_u64;
+ /// let mt1 = Mt19937GenRand64::from(seed);
+ /// let mt2 = Mt19937GenRand64::new(seed);
+ /// assert_eq!(mt1, mt2);
+ ///
+ /// // Non-default MT seed
+ /// let seed = 9927_u64;
+ /// let mt1 = Mt19937GenRand64::from(seed);
+ /// let mt2 = Mt19937GenRand64::new(seed);
+ /// assert_eq!(mt1, mt2);
+ /// ```
+ ///
+ /// [`new`]: Self::new
+ #[inline]
+ fn from(seed: u64) -> Self {
+ Self::new(seed)
+ }
+}
+
+impl From<[u64; NN]> for Mt19937GenRand64 {
+ /// Recover the internal state of a Mersenne Twister using the past 312
+ /// samples.
+ ///
+ /// This conversion takes a history of samples from a RNG and returns a
+ /// RNG that will produce identical output to the RNG that supplied the
+ /// samples.
+ #[inline]
+ fn from(key: [u64; NN]) -> Self {
+ let mut mt = Self {
+ idx: NN,
+ state: [Wrapping(0); NN],
+ };
+ for (sample, out) in key.iter().copied().zip(mt.state.iter_mut()) {
+ *out = Wrapping(untemper(sample));
+ }
+ mt
+ }
+}
+
+impl TryFrom<&[u64]> for Mt19937GenRand64 {
+ type Error = RecoverRngError;
+
+ /// Attempt to recover the internal state of a Mersenne Twister using the
+ /// past 312 samples.
+ ///
+ /// This conversion takes a history of samples from a RNG and returns a
+ /// RNG that will produce identical output to the RNG that supplied the
+ /// samples.
+ ///
+ /// This conversion is implemented with [`Mt19937GenRand64::recover`].
+ ///
+ /// # Errors
+ ///
+ /// If `key` has less than 312 elements, an error is returned because there
+ /// is not enough data to fully initialize the RNG.
+ ///
+ /// If `key` has more than 312 elements, an error is returned because the
+ /// recovered RNG will not produce identical output to the RNG that supplied
+ /// the samples.
+ #[inline]
+ fn try_from(key: &[u64]) -> Result<Self, Self::Error> {
+ Self::recover(key.iter().copied())
+ }
+}
+
+impl Mt19937GenRand64 {
+ /// Default seed used by [`Mt19937GenRand64::new_unseeded`].
+ pub const DEFAULT_SEED: u64 = 5489_u64;
+
+ /// Create a new Mersenne Twister random number generator using the given
+ /// seed.
+ ///
+ /// # Examples
+ ///
+ /// ## Constructing with a `u64` seed
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand64;
+ /// let seed = 123_456_789_u64;
+ /// let mt1 = Mt19937GenRand64::new(seed);
+ /// let mt2 = Mt19937GenRand64::from(seed.to_le_bytes());
+ /// assert_eq!(mt1, mt2);
+ /// ```
+ ///
+ /// ## Constructing with default seed
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand64;
+ /// let mt1 = Mt19937GenRand64::new(Mt19937GenRand64::DEFAULT_SEED);
+ /// let mt2 = Mt19937GenRand64::new_unseeded();
+ /// assert_eq!(mt1, mt2);
+ /// ```
+ #[inline]
+ #[must_use]
+ pub fn new(seed: u64) -> Self {
+ let mut mt = Self {
+ idx: 0,
+ state: [Wrapping(0); NN],
+ };
+ mt.reseed(seed);
+ mt
+ }
+
+ /// Create a new Mersenne Twister random number generator using the given
+ /// key.
+ ///
+ /// Key can have any length.
+ #[inline]
+ #[must_use]
+ pub fn new_with_key<I>(key: I) -> Self
+ where
+ I: IntoIterator<Item = u64>,
+ I::IntoIter: Clone,
+ {
+ let mut mt = Self {
+ idx: 0,
+ state: [Wrapping(0); NN],
+ };
+ mt.reseed_with_key(key);
+ mt
+ }
+
+ /// Create a new Mersenne Twister random number generator using the default
+ /// fixed seed.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand64;
+ /// // Default MT seed
+ /// let seed = 5489_u64;
+ /// let mt = Mt19937GenRand64::new(seed);
+ /// let unseeded = Mt19937GenRand64::new_unseeded();
+ /// assert_eq!(mt, unseeded);
+ /// ```
+ #[inline]
+ #[must_use]
+ pub fn new_unseeded() -> Self {
+ Self::new(Self::DEFAULT_SEED)
+ }
+
+ /// Generate next `u64` output.
+ ///
+ /// `u64` is the native output of the generator. This function advances the
+ /// RNG step counter by one.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand64;
+ /// let mut mt = Mt19937GenRand64::new_unseeded();
+ /// assert_ne!(mt.next_u64(), mt.next_u64());
+ /// ```
+ #[inline]
+ pub fn next_u64(&mut self) -> u64 {
+ // Failing this check indicates that, somehow, the structure
+ // was not initialized.
+ debug_assert!(self.idx != 0);
+ if self.idx >= NN {
+ fill_next_state(self);
+ }
+ let Wrapping(x) = self.state[self.idx];
+ self.idx += 1;
+ temper(x)
+ }
+
+ /// Generate next `u32` output.
+ ///
+ /// This function is implemented by generating one `u64` from the RNG and
+ /// performing shifting and masking to turn it into a `u32` output.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand64;
+ /// let mut mt = Mt19937GenRand64::new_unseeded();
+ /// assert_ne!(mt.next_u32(), mt.next_u32());
+ /// ```
+ #[inline]
+ #[allow(clippy::cast_possible_truncation)]
+ pub fn next_u32(&mut self) -> u32 {
+ self.next_u64() as u32
+ }
+
+ /// Fill a buffer with bytes generated from the RNG.
+ ///
+ /// This method generates random `u64`s (the native output unit of the RNG)
+ /// until `dest` is filled.
+ ///
+ /// This method may discard some output bits if `dest.len()` is not a
+ /// multiple of 8.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand64;
+ /// let mut mt = Mt19937GenRand64::new_unseeded();
+ /// let mut buf = [0; 32];
+ /// mt.fill_bytes(&mut buf);
+ /// assert_ne!([0; 32], buf);
+ /// let mut buf = [0; 31];
+ /// mt.fill_bytes(&mut buf);
+ /// assert_ne!([0; 31], buf);
+ /// ```
+ #[inline]
+ pub fn fill_bytes(&mut self, dest: &mut [u8]) {
+ const CHUNK: usize = size_of::<u64>();
+ let mut dest_chunks = dest.chunks_exact_mut(CHUNK);
+
+ for next in &mut dest_chunks {
+ let chunk: [u8; CHUNK] = self.next_u64().to_le_bytes();
+ next.copy_from_slice(&chunk);
+ }
+
+ let remainder = dest_chunks.into_remainder();
+ if remainder.is_empty() {
+ return;
+ }
+ remainder
+ .iter_mut()
+ .zip(self.next_u64().to_le_bytes().iter())
+ .for_each(|(cell, &byte)| {
+ *cell = byte;
+ });
+ }
+
+ /// Attempt to recover the internal state of a Mersenne Twister using the
+ /// past 312 samples.
+ ///
+ /// This conversion takes a history of samples from a RNG and returns a
+ /// RNG that will produce identical output to the RNG that supplied the
+ /// samples.
+ ///
+ /// This constructor is also available as a [`TryFrom`] implementation for
+ /// `&[u32]`.
+ ///
+ /// # Errors
+ ///
+ /// If `key` has less than 312 elements, an error is returned because there
+ /// is not enough data to fully initialize the RNG.
+ ///
+ /// If `key` has more than 312 elements, an error is returned because the
+ /// recovered RNG will not produce identical output to the RNG that supplied
+ /// the samples.
+ #[inline]
+ pub fn recover<I>(key: I) -> Result<Self, RecoverRngError>
+ where
+ I: IntoIterator<Item = u64>,
+ {
+ let mut mt = Self {
+ idx: NN,
+ state: [Wrapping(0); NN],
+ };
+ let mut state = mt.state.iter_mut();
+ for sample in key {
+ let out = state.next().ok_or(RecoverRngError::TooManySamples(NN))?;
+ *out = Wrapping(untemper(sample));
+ }
+ // If the state iterator still has unfilled cells, the given iterator
+ // was too short. If there are no additional cells, return the
+ // initialized RNG.
+ if state.next().is_none() {
+ Ok(mt)
+ } else {
+ Err(RecoverRngError::TooFewSamples(NN))
+ }
+ }
+
+ /// Reseed a Mersenne Twister from a single `u64`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use rand_mt::Mt19937GenRand64;
+ /// // Default MT seed
+ /// let mut mt = Mt19937GenRand64::new_unseeded();
+ /// let first = mt.next_u64();
+ /// mt.fill_bytes(&mut [0; 512]);
+ /// // Default MT seed
+ /// mt.reseed(5489_u64);
+ /// assert_eq!(first, mt.next_u64());
+ /// ```
+ #[inline]
+ pub fn reseed(&mut self, seed: u64) {
+ self.idx = NN;
+ self.state[0] = Wrapping(seed);
+ for i in 1..NN {
+ self.state[i] = Wrapping(6_364_136_223_846_793_005)
+ * (self.state[i - 1] ^ (self.state[i - 1] >> 62))
+ + Wrapping(i as u64);
+ }
+ }
+
+ /// Reseed a Mersenne Twister from am iterator of `u64`s.
+ ///
+ /// Key can have any length.
+ #[inline]
+ #[allow(clippy::cast_possible_truncation)]
+ pub fn reseed_with_key<I>(&mut self, key: I)
+ where
+ I: IntoIterator<Item = u64>,
+ I::IntoIter: Clone,
+ {
+ self.reseed(19_650_218_u64);
+ let mut i = 1_usize;
+ for (j, piece) in key.into_iter().enumerate().cycle().take(NN) {
+ self.state[i] = (self.state[i]
+ ^ ((self.state[i - 1] ^ (self.state[i - 1] >> 62))
+ * Wrapping(3_935_559_000_370_003_845)))
+ + Wrapping(piece)
+ + Wrapping(j as u64);
+ i += 1;
+ if i >= NN {
+ self.state[0] = self.state[NN - 1];
+ i = 1;
+ }
+ }
+ for _ in 0..NN - 1 {
+ self.state[i] = (self.state[i]
+ ^ ((self.state[i - 1] ^ (self.state[i - 1] >> 62))
+ * Wrapping(2_862_933_555_777_941_757)))
+ - Wrapping(i as u64);
+ i += 1;
+ if i >= NN {
+ self.state[0] = self.state[NN - 1];
+ i = 1;
+ }
+ }
+ self.state[0] = Wrapping(1 << 63);
+ }
+}
+
+#[inline]
+fn temper(mut x: u64) -> u64 {
+ x ^= (x >> 29) & 0x5555_5555_5555_5555;
+ x ^= (x << 17) & 0x71d6_7fff_eda6_0000;
+ x ^= (x << 37) & 0xfff7_eee0_0000_0000;
+ x ^= x >> 43;
+ x
+}
+
+#[inline]
+fn untemper(mut x: u64) -> u64 {
+ // reverse `x ^= x >> 43;`
+ x ^= x >> 43;
+
+ // reverse `x ^= (x << 37) & 0xfff7_eee0_0000_0000;`
+ x ^= (x << 37) & 0xfff7_eee0_0000_0000;
+
+ // reverse `x ^= (x << 17) & 0x71d6_7fff_eda6_0000;`
+ x ^= (x << 17) & 0x0000_0003_eda6_0000;
+ x ^= (x << 17) & 0x0006_7ffc_0000_0000;
+ x ^= (x << 17) & 0x71d0_0000_0000_0000;
+
+ // reverse `x ^= (x >> 29) & 0x5555_5555_5555_5555;`
+ x ^= (x >> 29) & 0x0000_0005_5555_5540;
+ x ^= (x >> 29) & 0x0000_0000_0000_0015;
+
+ x
+}
+
+#[inline]
+fn fill_next_state(rng: &mut Mt19937GenRand64) {
+ for i in 0..NN - MM {
+ let x = (rng.state[i] & UM) | (rng.state[i + 1] & LM);
+ rng.state[i] = rng.state[i + MM] ^ (x >> 1) ^ ((x & ONE) * MATRIX_A);
+ }
+ for i in NN - MM..NN - 1 {
+ let x = (rng.state[i] & UM) | (rng.state[i + 1] & LM);
+ rng.state[i] = rng.state[i + MM - NN] ^ (x >> 1) ^ ((x & ONE) * MATRIX_A);
+ }
+ let x = (rng.state[NN - 1] & UM) | (rng.state[0] & LM);
+ rng.state[NN - 1] = rng.state[MM - 1] ^ (x >> 1) ^ ((x & ONE) * MATRIX_A);
+ rng.idx = 0;
+}
+
+#[cfg(test)]
+mod tests {
+ use core::convert::TryFrom;
+ use core::num::Wrapping;
+
+ use super::{Mt19937GenRand64, NN};
+ use crate::vectors::mt64::{STATE_SEEDED_BY_SLICE, STATE_SEEDED_BY_U64, TEST_OUTPUT};
+ use crate::RecoverRngError;
+
+ #[test]
+ fn seeded_state_from_u64_seed() {
+ let mt = Mt19937GenRand64::new(0x0123_4567_89ab_cdef_u64);
+ let mt_from_seed = Mt19937GenRand64::from(0x0123_4567_89ab_cdef_u64.to_le_bytes());
+ assert_eq!(mt.state, mt_from_seed.state);
+ for (&Wrapping(x), &y) in mt.state.iter().zip(STATE_SEEDED_BY_U64.iter()) {
+ assert_eq!(x, y);
+ }
+ for (&Wrapping(x), &y) in mt_from_seed.state.iter().zip(STATE_SEEDED_BY_U64.iter()) {
+ assert_eq!(x, y);
+ }
+ }
+
+ #[test]
+ fn seeded_state_from_u64_slice_key() {
+ let key = [0x12345_u64, 0x23456_u64, 0x34567_u64, 0x45678_u64];
+ let mt = Mt19937GenRand64::new_with_key(key.iter().copied());
+ for (&Wrapping(x), &y) in mt.state.iter().zip(STATE_SEEDED_BY_SLICE.iter()) {
+ assert_eq!(x, y);
+ }
+ }
+
+ #[test]
+ fn seed_with_empty_iter_returns() {
+ let _rng = Mt19937GenRand64::new_with_key(core::iter::empty());
+ }
+
+ #[test]
+ fn output_from_u64_slice_key() {
+ let key = [0x12345_u64, 0x23456_u64, 0x34567_u64, 0x45678_u64];
+ let mut mt = Mt19937GenRand64::new_with_key(key.iter().copied());
+ for &x in &TEST_OUTPUT {
+ assert_eq!(x, mt.next_u64());
+ }
+ }
+
+ #[test]
+ fn temper_untemper_is_identity() {
+ let mut buf = [0; 8];
+ for _ in 0..10_000 {
+ getrandom::getrandom(&mut buf).unwrap();
+ let x = u64::from_le_bytes(buf);
+ assert_eq!(x, super::untemper(super::temper(x)));
+ let x = u64::from_be_bytes(buf);
+ assert_eq!(x, super::untemper(super::temper(x)));
+ }
+ }
+
+ #[test]
+ fn untemper_temper_is_identity() {
+ let mut buf = [0; 8];
+ for _ in 0..10_000 {
+ getrandom::getrandom(&mut buf).unwrap();
+ let x = u64::from_le_bytes(buf);
+ assert_eq!(x, super::temper(super::untemper(x)));
+ let x = u64::from_be_bytes(buf);
+ assert_eq!(x, super::temper(super::untemper(x)));
+ }
+ }
+
+ #[test]
+ fn recovery_via_from() {
+ let mut buf = [0; 8];
+ for _ in 0..100 {
+ getrandom::getrandom(&mut buf).unwrap();
+ let seed = u64::from_le_bytes(buf);
+ for skip in 0..256 {
+ let mut orig_mt = Mt19937GenRand64::new(seed);
+ // skip some samples so the RNG is in an intermediate state
+ for _ in 0..skip {
+ orig_mt.next_u64();
+ }
+ let mut samples = [0; 312];
+ for sample in &mut samples {
+ *sample = orig_mt.next_u64();
+ }
+ let mut recovered_mt = Mt19937GenRand64::from(samples);
+ for _ in 0..312 * 2 {
+ assert_eq!(orig_mt.next_u64(), recovered_mt.next_u64());
+ }
+ }
+ }
+ }
+
+ #[test]
+ fn recovery_via_recover() {
+ let mut buf = [0; 8];
+ for _ in 0..100 {
+ getrandom::getrandom(&mut buf).unwrap();
+ let seed = u64::from_le_bytes(buf);
+ for skip in 0..256 {
+ let mut orig_mt = Mt19937GenRand64::new(seed);
+ // skip some samples so the RNG is in an intermediate state
+ for _ in 0..skip {
+ orig_mt.next_u64();
+ }
+ let mut samples = [0; 312];
+ for sample in &mut samples {
+ *sample = orig_mt.next_u64();
+ }
+ let mut recovered_mt = Mt19937GenRand64::recover(samples.iter().copied()).unwrap();
+ for _ in 0..312 * 2 {
+ assert_eq!(orig_mt.next_u64(), recovered_mt.next_u64());
+ }
+ }
+ }
+ }
+
+ #[test]
+ fn recover_required_exact_sample_length_via_from() {
+ assert_eq!(
+ Mt19937GenRand64::try_from(&[0; 0][..]),
+ Err(RecoverRngError::TooFewSamples(NN))
+ );
+ assert_eq!(
+ Mt19937GenRand64::try_from(&[0; 1][..]),
+ Err(RecoverRngError::TooFewSamples(NN))
+ );
+ assert_eq!(
+ Mt19937GenRand64::try_from(&[0; 311][..]),
+ Err(RecoverRngError::TooFewSamples(NN))
+ );
+ Mt19937GenRand64::try_from(&[0; 312][..]).unwrap();
+ assert_eq!(
+ Mt19937GenRand64::try_from(&[0; 313][..]),
+ Err(RecoverRngError::TooManySamples(NN))
+ );
+ assert_eq!(
+ Mt19937GenRand64::try_from(&[0; 1000][..]),
+ Err(RecoverRngError::TooManySamples(NN))
+ );
+ }
+
+ #[test]
+ fn recover_required_exact_sample_length_via_recover() {
+ assert_eq!(
+ Mt19937GenRand64::recover([0; 0].iter().copied()),
+ Err(RecoverRngError::TooFewSamples(NN))
+ );
+ assert_eq!(
+ Mt19937GenRand64::recover([0; 1].iter().copied()),
+ Err(RecoverRngError::TooFewSamples(NN))
+ );
+ assert_eq!(
+ Mt19937GenRand64::recover([0; 311].iter().copied()),
+ Err(RecoverRngError::TooFewSamples(NN))
+ );
+ Mt19937GenRand64::recover([0; 312].iter().copied()).unwrap();
+ assert_eq!(
+ Mt19937GenRand64::recover([0; 313].iter().copied()),
+ Err(RecoverRngError::TooManySamples(NN))
+ );
+ assert_eq!(
+ Mt19937GenRand64::recover([0; 1000].iter().copied()),
+ Err(RecoverRngError::TooManySamples(NN))
+ );
+ }
+
+ #[test]
+ #[cfg(feature = "std")]
+ fn fmt_debug_does_not_leak_seed() {
+ use core::fmt::Write as _;
+ use std::string::String;
+
+ let random = Mt19937GenRand64::new(874);
+
+ let mut buf = String::new();
+ write!(&mut buf, "{:?}", random).unwrap();
+ assert!(!buf.contains("874"));
+ assert_eq!(buf, "Mt19937GenRand64 {}");
+
+ let random = Mt19937GenRand64::new(123_456);
+
+ let mut buf = String::new();
+ write!(&mut buf, "{:?}", random).unwrap();
+ assert!(!buf.contains("123456"));
+ assert_eq!(buf, "Mt19937GenRand64 {}");
+ }
+
+ #[test]
+ fn default_is_new_unseeded() {
+ let mut default = Mt19937GenRand64::default();
+ let mut unseeded = Mt19937GenRand64::new_unseeded();
+
+ assert_eq!(default, unseeded);
+ for _ in 0..1024 {
+ assert_eq!(default.next_u64(), unseeded.next_u64());
+ }
+ }
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177
// src/mt64/rand.rs
+//
+// Copyright (c) 2015,2017 rust-mersenne-twister developers
+// Copyright (c) 2020 Ryan Lopopolo <rjl@hyperbo.la>
+//
+// Licensed under the Apache License, Version 2.0
+// <LICENSE-APACHE> or <http://www.apache.org/licenses/LICENSE-2.0> or the MIT
+// license <LICENSE-MIT> or <http://opensource.org/licenses/MIT>, at your
+// option. All files in the project carrying such notice may not be copied,
+// modified, or distributed except according to those terms.
+
+use rand_core::{Error, RngCore, SeedableRng};
+
+use super::Mt19937GenRand64;
+
+impl SeedableRng for Mt19937GenRand64 {
+ type Seed = [u8; 8];
+
+ /// Reseed from a little endian encoded `u64`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use rand_core::{RngCore, SeedableRng};
+ /// # use rand_mt::Mt19937GenRand64;
+ /// // Default MT seed
+ /// let seed = 5489_u64.to_le_bytes();
+ /// let mut mt = Mt19937GenRand64::from_seed(seed);
+ /// assert_ne!(mt.next_u64(), mt.next_u64());
+ /// ```
+ #[inline]
+ fn from_seed(seed: Self::Seed) -> Self {
+ Self::from(seed)
+ }
+}
+
+impl RngCore for Mt19937GenRand64 {
+ /// Generate next `u64` output.
+ ///
+ /// `u64` is the native output of the generator. This function advances the
+ /// RNG step counter by one.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rand_core::RngCore;
+ /// use rand_mt::Mt19937GenRand64;
+ ///
+ /// let mut rng = Mt19937GenRand64::new_unseeded();
+ /// # fn example<T: RngCore>(mut rng: T) {
+ /// assert_ne!(rng.next_u64(), rng.next_u64());
+ /// # }
+ /// # example(rng);
+ /// ```
+ #[inline]
+ fn next_u64(&mut self) -> u64 {
+ Self::next_u64(self)
+ }
+
+ /// Generate next `u32` output.
+ ///
+ /// This function is implemented by generating one `u64` from the RNG and
+ /// performing shifting and masking to turn it into a `u32` output.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rand_core::RngCore;
+ /// use rand_mt::Mt19937GenRand64;
+ ///
+ /// let mut rng = Mt19937GenRand64::new_unseeded();
+ /// # fn example<T: RngCore>(mut rng: T) {
+ /// assert_ne!(rng.next_u32(), rng.next_u32());
+ /// # }
+ /// # example(rng);
+ /// ```
+ #[inline]
+ fn next_u32(&mut self) -> u32 {
+ Self::next_u32(self)
+ }
+
+ /// Fill a buffer with bytes generated from the RNG.
+ ///
+ /// This method generates random `u64`s (the native output unit of the RNG)
+ /// until `dest` is filled.
+ ///
+ /// This method may discard some output bits if `dest.len()` is not a
+ /// multiple of 8.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rand_core::RngCore;
+ /// use rand_mt::Mt19937GenRand64;
+ ///
+ /// let mut rng = Mt19937GenRand64::new_unseeded();
+ /// # fn example<T: RngCore>(mut rng: T) {
+ /// let mut buf = [0; 32];
+ /// rng.fill_bytes(&mut buf);
+ /// assert_ne!([0; 32], buf);
+ /// let mut buf = [0; 31];
+ /// rng.fill_bytes(&mut buf);
+ /// assert_ne!([0; 31], buf);
+ /// # }
+ /// # example(rng);
+ /// ```
+ #[inline]
+ fn fill_bytes(&mut self, dest: &mut [u8]) {
+ Self::fill_bytes(self, dest);
+ }
+
+ /// Fill a buffer with bytes generated from the RNG.
+ ///
+ /// This method generates random `u64`s (the native output unit of the RNG)
+ /// until `dest` is filled.
+ ///
+ /// This method may discard some output bits if `dest.len()` is not a
+ /// multiple of 8.
+ ///
+ /// `try_fill_bytes` is implemented with [`fill_bytes`](RngCore::fill_bytes)
+ /// and is infallible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rand_core::RngCore;
+ /// use rand_mt::Mt19937GenRand64;
+ ///
+ /// let mut rng = Mt19937GenRand64::new_unseeded();
+ /// # fn example<T: RngCore>(mut rng: T) -> Result<(), rand_core::Error> {
+ /// let mut buf = [0; 32];
+ /// rng.try_fill_bytes(&mut buf)?;
+ /// assert_ne!([0; 32], buf);
+ /// let mut buf = [0; 31];
+ /// rng.try_fill_bytes(&mut buf)?;
+ /// assert_ne!([0; 31], buf);
+ /// # Ok(())
+ /// # }
+ /// # example(rng).unwrap()
+ /// ```
+ #[inline]
+ fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+ Self::fill_bytes(self, dest);
+ Ok(())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use core::num::Wrapping;
+ use rand_core::{RngCore, SeedableRng};
+
+ use super::Mt19937GenRand64;
+ use crate::vectors::mt64::{STATE_SEEDED_BY_U64, TEST_OUTPUT};
+
+ #[test]
+ fn seeded_state_from_u64_seed() {
+ let mt = Mt19937GenRand64::new(0x0123_4567_89ab_cdef_u64);
+ let mt_from_seed = Mt19937GenRand64::from_seed(0x0123_4567_89ab_cdef_u64.to_le_bytes());
+ assert_eq!(mt.state, mt_from_seed.state);
+ for (&Wrapping(x), &y) in mt.state.iter().zip(STATE_SEEDED_BY_U64.iter()) {
+ assert_eq!(x, y);
+ }
+ for (&Wrapping(x), &y) in mt_from_seed.state.iter().zip(STATE_SEEDED_BY_U64.iter()) {
+ assert_eq!(x, y);
+ }
+ }
+
+ #[test]
+ fn output_from_u64_slice_key() {
+ let key = [0x12345_u64, 0x23456_u64, 0x34567_u64, 0x45678_u64];
+ let mut mt = Mt19937GenRand64::new_with_key(key.iter().copied());
+ for &x in &TEST_OUTPUT {
+ assert_eq!(x, RngCore::next_u64(&mut mt));
+ }
+ }
+}
+
fn:
) to \
+ restrict the search to a given item kind.","Accepted kinds are: fn
, mod
, struct
, \
+ enum
, trait
, type
, macro
, \
+ and const
.","Search functions by type signature (e.g., vec -> usize
or \
+ -> vec
or String, enum:Cow -> bool
)","You can look for items with an exact name by putting double quotes around \
+ your request: \"string\"
","Look for functions that accept or return \
+ slices and \
+ arrays by writing \
+ square brackets (e.g., -> [u8]
or [] -> Option
)","Look for items inside another one by searching for a path: vec::Vec
",].map(x=>""+x+"
").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="${value.replaceAll(" ", " ")}
`}else{error[index]=value}});output+=`source
. Read moreReturn a new Mt19937GenRand32
with the default seed.
Equivalent to calling Mt19937GenRand32::new_unseeded
.
Construct a Mersenne Twister RNG from 4 bytes.
\nThe given bytes are treated as a little endian encoded u32
.
// Default MT seed\nlet seed = 5489_u32.to_le_bytes();\nlet mut mt = Mt19937GenRand32::from(seed);\nassert_ne!(mt.next_u32(), mt.next_u32());
This constructor is equivalent to passing a little endian encoded u32
.
// Default MT seed\nlet seed = 5489_u32.to_le_bytes();\nlet mt1 = Mt19937GenRand32::from(seed);\nlet mt2 = Mt19937GenRand32::new(5489_u32);\nassert_eq!(mt1, mt2);
Construct a Mersenne Twister RNG from a u32
seed.
This function is equivalent to new
.
// Default MT seed\nlet seed = 5489_u32;\nlet mt1 = Mt19937GenRand32::from(seed);\nlet mt2 = Mt19937GenRand32::new(seed);\nassert_eq!(mt1, mt2);\n\n// Non-default MT seed\nlet seed = 9927_u32;\nlet mt1 = Mt19937GenRand32::from(seed);\nlet mt2 = Mt19937GenRand32::new(seed);\nassert_eq!(mt1, mt2);
Default seed used by Mt19937GenRand32::new_unseeded
.
Create a new Mersenne Twister random number generator using the given\nseed.
\nu32
seedlet seed = 123_456_789_u32;\nlet mt1 = Mt19937GenRand32::new(seed);\nlet mt2 = Mt19937GenRand32::from(seed.to_le_bytes());\nassert_eq!(mt1, mt2);
let mt1 = Mt19937GenRand32::new(Mt19937GenRand32::DEFAULT_SEED);\nlet mt2 = Mt19937GenRand32::new_unseeded();\nassert_eq!(mt1, mt2);
Create a new Mersenne Twister random number generator using the given\nkey.
\nKey can have any length.
\nCreate a new Mersenne Twister random number generator using the default\nfixed seed.
\n// Default MT seed\nlet seed = 5489_u32;\nlet mt = Mt19937GenRand32::new(seed);\nlet unseeded = Mt19937GenRand32::new_unseeded();\nassert_eq!(mt, unseeded);
Generate next u64
output.
This function is implemented by generating two u32
s from the RNG and\nperforming shifting and masking to turn them into a u64
output.
let mut mt = Mt19937GenRand32::new_unseeded();\nassert_ne!(mt.next_u64(), mt.next_u64());
Generate next u32
output.
u32
is the native output of the generator. This function advances the\nRNG step counter by one.
let mut mt = Mt19937GenRand32::new_unseeded();\nassert_ne!(mt.next_u32(), mt.next_u32());
Fill a buffer with bytes generated from the RNG.
\nThis method generates random u32
s (the native output unit of the RNG)\nuntil dest
is filled.
This method may discard some output bits if dest.len()
is not a\nmultiple of 4.
let mut mt = Mt19937GenRand32::new_unseeded();\nlet mut buf = [0; 32];\nmt.fill_bytes(&mut buf);\nassert_ne!([0; 32], buf);\nlet mut buf = [0; 31];\nmt.fill_bytes(&mut buf);\nassert_ne!([0; 31], buf);
Attempt to recover the internal state of a Mersenne Twister using the\npast 624 samples.
\nThis conversion takes a history of samples from a RNG and returns a\nRNG that will produce identical output to the RNG that supplied the\nsamples.
\nThis constructor is also available as a TryFrom
implementation for\n&[u32]
.
If key
has less than 624 elements, an error is returned because there\nis not enough data to fully initialize the RNG.
If key
has more than 624 elements, an error is returned because the\nrecovered RNG will not produce identical output to the RNG that supplied\nthe samples.
Reseed a Mersenne Twister from a single u32
.
// Default MT seed\nlet mut mt = Mt19937GenRand32::new_unseeded();\nlet first = mt.next_u32();\nmt.fill_bytes(&mut [0; 512]);\n// Default MT seed\nmt.reseed(5489_u32);\nassert_eq!(first, mt.next_u32());
Reseed a Mersenne Twister from am iterator of u32
s.
Key can have any length.
\nGenerate next u64
output.
This function is implemented by generating two u32
s from the RNG and\nperforming shifting and masking to turn them into a u64
output.
use rand_core::RngCore;\nuse rand_mt::Mt19937GenRand32;\n\nlet mut rng = Mt19937GenRand32::new_unseeded();\nassert_ne!(rng.next_u64(), rng.next_u64());
Generate next u32
output.
u32
is the native output of the generator. This function advances the\nRNG step counter by one.
use rand_core::RngCore;\nuse rand_mt::Mt19937GenRand32;\n\nlet mut rng = Mt19937GenRand32::new_unseeded();\nassert_ne!(rng.next_u32(), rng.next_u32());
Fill a buffer with bytes generated from the RNG.
\nThis method generates random u32
s (the native output unit of the RNG)\nuntil dest
is filled.
This method may discard some output bits if dest.len()
is not a\nmultiple of 4.
use rand_core::RngCore;\nuse rand_mt::Mt19937GenRand32;\n\nlet mut rng = Mt19937GenRand32::new_unseeded();\nlet mut buf = [0; 32];\nrng.fill_bytes(&mut buf);\nassert_ne!([0; 32], buf);\nlet mut buf = [0; 31];\nrng.fill_bytes(&mut buf);\nassert_ne!([0; 31], buf);
Fill a buffer with bytes generated from the RNG.
\nThis method generates random u32
s (the native output unit of the RNG)\nuntil dest
is filled.
This method may discard some output bits if dest.len()
is not a\nmultiple of 4.
try_fill_bytes
is implemented with fill_bytes
\nand is infallible.
use rand_core::RngCore;\nuse rand_mt::Mt19937GenRand32;\n\nlet mut rng = Mt19937GenRand32::new_unseeded();\nlet mut buf = [0; 32];\nrng.try_fill_bytes(&mut buf)?;\nassert_ne!([0; 32], buf);\nlet mut buf = [0; 31];\nrng.try_fill_bytes(&mut buf)?;\nassert_ne!([0; 31], buf);
Reseed from a little endian encoded u32
.
use rand_core::{RngCore, SeedableRng};\nuse rand_mt::Mt19937GenRand32;\n\n// Default MT seed\nlet seed = 5489_u32.to_le_bytes();\nlet mut rng = Mt19937GenRand32::from_seed(seed);\nassert_ne!(rng.next_u32(), rng.next_u32());
u8
\narrays (we recommend [u8; N]
for some N
). Read moreu64
seed. Read moreAttempt to recover the internal state of a Mersenne Twister using the\npast 624 samples.
\nThis conversion takes a history of samples from a RNG and returns a\nRNG that will produce identical output to the RNG that supplied the\nsamples.
\nThis conversion is implemented with Mt19937GenRand32::recover
.
If key
has less than 624 elements, an error is returned because there\nis not enough data to fully initialize the RNG.
If key
has more than 624 elements, an error is returned because the\nrecovered RNG will not produce identical output to the RNG that supplied\nthe samples.
source
. Read moreReturn a new Mt19937GenRand64
with the default seed.
Equivalent to calling Mt19937GenRand64::new_unseeded
.
Construct a Mersenne Twister RNG from a u64
seed.
This function is equivalent to new
.
// Default MT seed\nlet seed = 5489_u64;\nlet mt1 = Mt19937GenRand64::from(seed);\nlet mt2 = Mt19937GenRand64::new(seed);\nassert_eq!(mt1, mt2);\n\n// Non-default MT seed\nlet seed = 9927_u64;\nlet mt1 = Mt19937GenRand64::from(seed);\nlet mt2 = Mt19937GenRand64::new(seed);\nassert_eq!(mt1, mt2);
Default seed used by Mt19937GenRand64::new_unseeded
.
Create a new Mersenne Twister random number generator using the given\nseed.
\nu64
seedlet seed = 123_456_789_u64;\nlet mt1 = Mt19937GenRand64::new(seed);\nlet mt2 = Mt19937GenRand64::from(seed.to_le_bytes());\nassert_eq!(mt1, mt2);
let mt1 = Mt19937GenRand64::new(Mt19937GenRand64::DEFAULT_SEED);\nlet mt2 = Mt19937GenRand64::new_unseeded();\nassert_eq!(mt1, mt2);
Create a new Mersenne Twister random number generator using the given\nkey.
\nKey can have any length.
\nCreate a new Mersenne Twister random number generator using the default\nfixed seed.
\n// Default MT seed\nlet seed = 5489_u64;\nlet mt = Mt19937GenRand64::new(seed);\nlet unseeded = Mt19937GenRand64::new_unseeded();\nassert_eq!(mt, unseeded);
Generate next u64
output.
u64
is the native output of the generator. This function advances the\nRNG step counter by one.
let mut mt = Mt19937GenRand64::new_unseeded();\nassert_ne!(mt.next_u64(), mt.next_u64());
Generate next u32
output.
This function is implemented by generating one u64
from the RNG and\nperforming shifting and masking to turn it into a u32
output.
let mut mt = Mt19937GenRand64::new_unseeded();\nassert_ne!(mt.next_u32(), mt.next_u32());
Fill a buffer with bytes generated from the RNG.
\nThis method generates random u64
s (the native output unit of the RNG)\nuntil dest
is filled.
This method may discard some output bits if dest.len()
is not a\nmultiple of 8.
let mut mt = Mt19937GenRand64::new_unseeded();\nlet mut buf = [0; 32];\nmt.fill_bytes(&mut buf);\nassert_ne!([0; 32], buf);\nlet mut buf = [0; 31];\nmt.fill_bytes(&mut buf);\nassert_ne!([0; 31], buf);
Attempt to recover the internal state of a Mersenne Twister using the\npast 312 samples.
\nThis conversion takes a history of samples from a RNG and returns a\nRNG that will produce identical output to the RNG that supplied the\nsamples.
\nThis constructor is also available as a TryFrom
implementation for\n&[u32]
.
If key
has less than 312 elements, an error is returned because there\nis not enough data to fully initialize the RNG.
If key
has more than 312 elements, an error is returned because the\nrecovered RNG will not produce identical output to the RNG that supplied\nthe samples.
Reseed a Mersenne Twister from a single u64
.
// Default MT seed\nlet mut mt = Mt19937GenRand64::new_unseeded();\nlet first = mt.next_u64();\nmt.fill_bytes(&mut [0; 512]);\n// Default MT seed\nmt.reseed(5489_u64);\nassert_eq!(first, mt.next_u64());
Reseed a Mersenne Twister from am iterator of u64
s.
Key can have any length.
\nGenerate next u64
output.
u64
is the native output of the generator. This function advances the\nRNG step counter by one.
use rand_core::RngCore;\nuse rand_mt::Mt19937GenRand64;\n\nlet mut rng = Mt19937GenRand64::new_unseeded();\nassert_ne!(rng.next_u64(), rng.next_u64());
Generate next u32
output.
This function is implemented by generating one u64
from the RNG and\nperforming shifting and masking to turn it into a u32
output.
use rand_core::RngCore;\nuse rand_mt::Mt19937GenRand64;\n\nlet mut rng = Mt19937GenRand64::new_unseeded();\nassert_ne!(rng.next_u32(), rng.next_u32());
Fill a buffer with bytes generated from the RNG.
\nThis method generates random u64
s (the native output unit of the RNG)\nuntil dest
is filled.
This method may discard some output bits if dest.len()
is not a\nmultiple of 8.
use rand_core::RngCore;\nuse rand_mt::Mt19937GenRand64;\n\nlet mut rng = Mt19937GenRand64::new_unseeded();\nlet mut buf = [0; 32];\nrng.fill_bytes(&mut buf);\nassert_ne!([0; 32], buf);\nlet mut buf = [0; 31];\nrng.fill_bytes(&mut buf);\nassert_ne!([0; 31], buf);
Fill a buffer with bytes generated from the RNG.
\nThis method generates random u64
s (the native output unit of the RNG)\nuntil dest
is filled.
This method may discard some output bits if dest.len()
is not a\nmultiple of 8.
try_fill_bytes
is implemented with fill_bytes
\nand is infallible.
use rand_core::RngCore;\nuse rand_mt::Mt19937GenRand64;\n\nlet mut rng = Mt19937GenRand64::new_unseeded();\nlet mut buf = [0; 32];\nrng.try_fill_bytes(&mut buf)?;\nassert_ne!([0; 32], buf);\nlet mut buf = [0; 31];\nrng.try_fill_bytes(&mut buf)?;\nassert_ne!([0; 31], buf);
Reseed from a little endian encoded u64
.
// Default MT seed\nlet seed = 5489_u64.to_le_bytes();\nlet mut mt = Mt19937GenRand64::from_seed(seed);\nassert_ne!(mt.next_u64(), mt.next_u64());
u8
\narrays (we recommend [u8; N]
for some N
). Read moreu64
seed. Read moreAttempt to recover the internal state of a Mersenne Twister using the\npast 312 samples.
\nThis conversion takes a history of samples from a RNG and returns a\nRNG that will produce identical output to the RNG that supplied the\nsamples.
\nThis conversion is implemented with Mt19937GenRand64::recover
.
If key
has less than 312 elements, an error is returned because there\nis not enough data to fully initialize the RNG.
If key
has more than 312 elements, an error is returned because the\nrecovered RNG will not produce identical output to the RNG that supplied\nthe samples.