Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // implementing mystical rand5() using existing library
- fn rand5() -> u64 {
- rand::random::<u64>() % 5
- }
- // on each step val is a random number in range (0..max-1), this is how entropy is stored
- struct Generator {
- val : u64,
- max : u64,
- // just statistics...
- entropy_input : f64,
- entropy_output : f64,
- }
- impl Generator {
- fn new() -> Generator {
- Generator{
- val : 0,
- max : 1,
- entropy_input : 0.0,
- entropy_output : 0.0,
- }
- }
- fn rand(&mut self, n : u32) -> u32 {
- loop {
- let quotient = self.max / (n as u64);
- let good_max = quotient * (n as u64);
- if good_max > self.val {
- let res = (self.val % (n as u64)) as u32;
- self.val /= n as u64;
- self.max = quotient;
- self.entropy_output += (n as f64).log(2.0);
- return res;
- } else {
- // next line is "val += max * rand5()" but with int64 overflow check
- self.val = self.max.checked_mul(rand5()).expect("Generator overheated!")
- .checked_add(self.val).expect("Generator overheated!");
- // next line is "max *= 5" but with int64 overflow check
- self.max *= self.max.checked_mul(5).expect("Generator overheated!");
- self.entropy_input += 5f64.log(2.0);
- }
- }
- }
- }
- fn main() {
- let mut gen = Generator::new();
- for _i in 0..5000 {
- print!("{}", gen.rand(7));
- }
- println!("");
- println!("Entory consumed: {}", gen.entropy_input);
- println!("Entory produced: {}", gen.entropy_output);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement