Skip to content

Commit

Permalink
seed_from_u64: use newpavlov's suggestion
Browse files Browse the repository at this point in the history
  • Loading branch information
dhardy committed Jan 2, 2021
1 parent eb4b8a4 commit 594aed8
Showing 1 changed file with 16 additions and 6 deletions.
22 changes: 16 additions & 6 deletions rand_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,20 +300,30 @@ pub trait SeedableRng: Sized {
/// 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
const MUL: u64 = 6364136223846793005;
const INC: u64 = 11634580027462260723;
fn pcg32(state: &mut u64) -> [u8; 4] {
const MUL: u64 = 6364136223846793005;
const INC: u64 = 11634580027462260723;

let mut seed = Self::Seed::default();
for chunk in seed.as_mut().chunks_mut(4) {
// 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);
*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);
chunk.copy_from_slice(&x.to_le_bytes()[..chunk.len()]);
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)
Expand Down

0 comments on commit 594aed8

Please sign in to comment.