# lcg-tools i'm putting all the neat LCG utilities I use in this library so i can stop copy/pasting python functions from old writeups every time i have to break an lcg for a CTF. Currently it can solve an LCG forward and backwards and derive parameters when provided a collection of values ```rust #[cfg(test)] mod tests { use crate::{crack_lcg, LCG}; use num::ToPrimitive; use num_bigint::ToBigInt; #[test] fn it_generates_numbers_correctly_forward_and_backwards() { let mut rand = LCG { state: 32760.to_bigint().unwrap(), a: 5039.to_bigint().unwrap(), c: 76581.to_bigint().unwrap(), m: 479001599.to_bigint().unwrap(), }; let mut forward = (&mut rand).take(10).collect::>(); assert_eq!( forward, vec![ 165154221.to_bigint().unwrap(), 186418737.to_bigint().unwrap(), 41956685.to_bigint().unwrap(), 180107137.to_bigint().unwrap(), 330911418.to_bigint().unwrap(), 58145764.to_bigint().unwrap(), 326604388.to_bigint().unwrap(), 389095148.to_bigint().unwrap(), 96982646.to_bigint().unwrap(), 113998795.to_bigint().unwrap() ] ); forward.reverse(); rand.rand(); assert_eq!( (0..10).filter_map(|_| rand.prev()).collect::>(), forward ); } #[test] fn it_cracks_lcg_correctly() { let mut rand = LCG { state: 32760.to_bigint().unwrap(), a: 5039.to_bigint().unwrap(), c: 0.to_bigint().unwrap(), m: 479001599.to_bigint().unwrap(), }; let cracked_lcg = crack_lcg( &(&mut rand) .take(10) .map(|x| x.to_isize().unwrap()) .collect::>(), ) .unwrap(); assert_eq!(rand, cracked_lcg); } } ```