#![allow(dead_code)]
pub struct Rng {
pub s:u64, pub a:u64, pub b:u64, pub c:u64, }
impl Rng {
pub fn new( init:Option<[u8;32]> ) -> Rng {
let newrng:Rng;
let mut eb:[u8;32];
match init {
Some(data) => {
eb = data;
}
None => {
eb = [0u8;32];
match getrandom::getrandom(&mut eb) {
Ok(_x) => {},
Err(x) => {panic!("nz::Rng::new() Cannot seed the RNG in a secure manner.\n{:?}", x)}
}
}
};
let mut bytes = [0u64;4];
bytes[0] = u64::from_be_bytes( [eb[0], eb[1], eb[2], eb[3], eb[4], eb[5], eb[6], eb[7]] );
bytes[1] = u64::from_be_bytes( [eb[8], eb[9], eb[10], eb[11], eb[12], eb[13], eb[14], eb[15]] );
bytes[2] = u64::from_be_bytes( [eb[16], eb[17], eb[18], eb[19], eb[20], eb[21], eb[22], eb[23]] );
bytes[3] = u64::from_be_bytes( [eb[24], eb[25], eb[26], eb[27], eb[28], eb[29], eb[30], eb[31]] );
newrng = Rng {
a:bytes[0],
b:bytes[1],
c:bytes[2],
s:bytes[3],
};
return newrng;
}
pub fn get(&mut self) -> u64 {
let output = self.a ^ self.b ^ self.c;
self.s += 1;
if self.s % 1024 == 0 {
let temp = self.a;
self.a = self.c;
self.c = temp;
}
if self.s % 64 == 0 {
self.b = ( self.b << 13 ) | ( self.b >> ( 64 - 13 ) );
}
self.a = (self.a << 11) | (self.a >> (64 - 11));
self.c = ( ( self.c << 17 ) | ( self.c >> ( 64 - 17 ) ) ).wrapping_add(output);
return output;
}
}