time-based preseeded rand

This commit is contained in:
Dominik Maier 2020-11-09 21:04:46 +01:00
parent 8454a52856
commit 7f8734e161
4 changed files with 28 additions and 9 deletions

View File

@ -308,7 +308,7 @@ mod tests {
#[test] #[test]
fn test_queuecorpus() { fn test_queuecorpus() {
let rand = Xoshiro256StarRand::new_rr(); let rand = Xoshiro256StarRand::preseeded_rr();
let mut q = QueueCorpus::new(OnDiskCorpus::new(&rand, PathBuf::from("fancy/path"))); let mut q = QueueCorpus::new(OnDiskCorpus::new(&rand, PathBuf::from("fancy/path")));
let i = BytesInput::new(vec![0; 4]); let i = BytesInput::new(vec![0; 4]);
let t = Testcase::with_filename_rr(i, PathBuf::from("fancyfile")); let t = Testcase::with_filename_rr(i, PathBuf::from("fancyfile"));

View File

@ -211,7 +211,7 @@ mod tests {
#[test] #[test]
fn test_engine() { fn test_engine() {
let rand = Xoshiro256StarRand::new_rr(); let rand = Xoshiro256StarRand::preseeded_rr();
let mut corpus = InMemoryCorpus::<BytesInput, _>::new(&rand); let mut corpus = InMemoryCorpus::<BytesInput, _>::new(&rand);
let testcase = Testcase::new_rr(BytesInput::new(vec![0; 4])); let testcase = Testcase::new_rr(BytesInput::new(vec![0; 4]));

View File

@ -46,7 +46,7 @@ mod tests {
#[test] #[test]
fn test_input() { fn test_input() {
let mut rand = Xoshiro256StarRand::new(); let mut rand = Xoshiro256StarRand::preseeded();
assert_ne!(rand.next(), rand.next()); assert_ne!(rand.next(), rand.next());
assert!(rand.below(100) < 100); assert!(rand.below(100) < 100);
assert_eq!(rand.below(1), 0); assert_eq!(rand.below(1), 0);

View File

@ -4,6 +4,8 @@ use std::cell::RefCell;
use std::debug_assert; use std::debug_assert;
use std::fmt::Debug; use std::fmt::Debug;
use std::rc::Rc; use std::rc::Rc;
use std::time::{SystemTime, UNIX_EPOCH};
use xxhash_rust::xxh3::xxh3_64_with_seed; use xxhash_rust::xxh3::xxh3_64_with_seed;
/// Ways to get random around here /// Ways to get random around here
@ -106,15 +108,29 @@ impl Rand for Xoshiro256StarRand {
} }
impl Xoshiro256StarRand { impl Xoshiro256StarRand {
pub fn new() -> Self { /// Creates a new Xoshiro rand with the given seed
pub fn new(seed: u64) -> Self {
let mut ret: Xoshiro256StarRand = Default::default(); let mut ret: Xoshiro256StarRand = Default::default();
ret.set_seed(0); // TODO: Proper random seed? ret.set_seed(seed); // TODO: Proper random seed?
ret ret
} }
pub fn new_rr() -> Rc<RefCell<Self>> { /// Creates a new Xoshiro rand with the given seed, wrapped in a Rc<RefCell<T>>.
Rc::new(RefCell::new(Xoshiro256StarRand::new())) pub fn new_rr(seed: u64) -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(Self::new(seed)))
} }
/// Creates a rand instance, pre-seeded with the current time in nanoseconds.
pub fn preseeded() -> Self {
let seed = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_nanos() as u64;
Self::new(seed)
}
/// Creates a new rand instance, pre-seeded
pub fn preseeded_rr() -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(Self::preseeded()))
}
} }
/// Get the next higher power of two /// Get the next higher power of two
@ -134,7 +150,7 @@ mod tests {
#[test] #[test]
fn test_rand() { fn test_rand() {
let mut rand = Xoshiro256StarRand::new(); let mut rand = Xoshiro256StarRand::preseeded();
assert_ne!(rand.next(), rand.next()); assert_ne!(rand.next(), rand.next());
assert!(rand.below(100) < 100); assert!(rand.below(100) < 100);
assert_eq!(rand.below(1), 0); assert_eq!(rand.below(1), 0);
@ -142,6 +158,7 @@ mod tests {
assert!(rand.between(11, 20) > 10); assert!(rand.between(11, 20) > 10);
} }
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
struct HasRandTest<R> struct HasRandTest<R>
@ -164,7 +181,7 @@ mod tests {
#[test] #[test]
fn test_has_rand() { fn test_has_rand() {
let rand = Xoshiro256StarRand::new_rr(); let rand = Xoshiro256StarRand::preseeded_rr();
let has_rand = HasRandTest { let has_rand = HasRandTest {
rand: Rc::clone(&rand), rand: Rc::clone(&rand),
}; };
@ -173,6 +190,8 @@ mod tests {
assert_eq!(has_rand.rand_below(1), 0); assert_eq!(has_rand.rand_below(1), 0);
} }
#[test] #[test]
fn test_next_pow2() { fn test_next_pow2() {
assert_eq!(next_pow2(0), 0); assert_eq!(next_pow2(0), 0);