Skip to content

Commit bda9974

Browse files
authored
Merge pull request #1083 from dhardy/work
Fix #1082 (seed_from_u64 with non multiple of 4)
2 parents 34aa769 + 594aed8 commit bda9974

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

rand_core/CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
## [0.6.1] - 2020-12-31
7+
## [0.6.1] - 2021-01-03
8+
### Fixed
9+
- Avoid panic when using `RngCore::seed_from_u64` with a seed which is not a
10+
multiple of four (#1082)
811
### Other
912
- Enable all stable features in the playground (#1081)
1013

rand_core/src/lib.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -300,20 +300,30 @@ pub trait SeedableRng: Sized {
300300
/// considered a value-breaking change.
301301
fn seed_from_u64(mut state: u64) -> Self {
302302
// We use PCG32 to generate a u32 sequence, and copy to the seed
303-
const MUL: u64 = 6364136223846793005;
304-
const INC: u64 = 11634580027462260723;
303+
fn pcg32(state: &mut u64) -> [u8; 4] {
304+
const MUL: u64 = 6364136223846793005;
305+
const INC: u64 = 11634580027462260723;
305306

306-
let mut seed = Self::Seed::default();
307-
for chunk in seed.as_mut().chunks_mut(4) {
308307
// We advance the state first (to get away from the input value,
309308
// in case it has low Hamming Weight).
310-
state = state.wrapping_mul(MUL).wrapping_add(INC);
309+
*state = state.wrapping_mul(MUL).wrapping_add(INC);
310+
let state = *state;
311311

312312
// Use PCG output function with to_le to generate x:
313313
let xorshifted = (((state >> 18) ^ state) >> 27) as u32;
314314
let rot = (state >> 59) as u32;
315315
let x = xorshifted.rotate_right(rot);
316-
chunk.copy_from_slice(&x.to_le_bytes());
316+
x.to_le_bytes()
317+
}
318+
319+
let mut seed = Self::Seed::default();
320+
let mut iter = seed.as_mut().chunks_exact_mut(4);
321+
for chunk in &mut iter {
322+
chunk.copy_from_slice(&pcg32(&mut state));
323+
}
324+
let rem = iter.into_remainder();
325+
if !rem.is_empty() {
326+
rem.copy_from_slice(&pcg32(&mut state)[..rem.len()]);
317327
}
318328

319329
Self::from_seed(seed)

0 commit comments

Comments
 (0)