diff --git a/src/main.rs b/src/main.rs index d5c3fec..3f5816a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,7 +34,8 @@ fn main() { set3::challenge20(); set3::challenge21(); set3::challenge22(); + set3::challenge23(); } else { - set3::challenge22(); + set3::challenge23(); } } diff --git a/src/set3.rs b/src/set3.rs index 5eeebe0..8180867 100644 --- a/src/set3.rs +++ b/src/set3.rs @@ -8,6 +8,7 @@ use std::cell::RefCell; use std::collections::HashMap; use std::collections::HashSet; use std::io::{BufRead, BufReader}; +use std::time::{SystemTime, UNIX_EPOCH}; pub fn challenge17() { fn read(path: &str) -> Vec { @@ -317,5 +318,46 @@ pub fn challenge21() { } pub fn challenge22() { - println!("[xxxx] Challenge 22: TBD!"); + // let mut mt = mt19937::MT19937::new(); + fn unix_timestamp() -> u32 { + let start = SystemTime::now(); + let since_the_epoch = start + .duration_since(UNIX_EPOCH) + .expect("Time went backwards"); + since_the_epoch.as_secs() as u32 + } + + // Wait a random number of seconds between, I don't know, 40 and 1000. + let now = unix_timestamp(); + let wait_time: u32 = rand::thread_rng().gen_range(40..1000); + let seed = now + wait_time; + + // Seeds the RNG with the current Unix timestamp. + let mut mt = mt19937::MT19937::new(); + mt.seed(seed); + + // Returns the first 32 bit output of the RNG. + let rngout = mt.extract_number(); + + // From the 32 bit RNG output, discover the seed. + fn find_seed(rngout: u32) -> Option { + let mut mt = mt19937::MT19937::new(); + let start = unix_timestamp() - 2000; + for seed in start..(start + 4000) { + mt.seed(seed); + if rngout == mt.extract_number() { + return Some(seed); + } + } + None + } + + let found_seed = find_seed(rngout); + assert_eq!(seed, found_seed.unwrap()); + + println!("[done] Challenge 22: cracked MT19937 seed."); +} + +pub fn challenge23() { + println!("[xxxx] Challenge 23: tbd"); }