pub mod true_rng{
use candid::Principal;
use ic_cdk::call;
pub async fn async_generate() -> Result<usize, String >{
let (random_bytes,): (Vec<u8>,) = call(Principal::management_canister(), "raw_rand", ()).await.map_err(|err| format!("{:?}", err))?;
let random_number = usize::from_be_bytes(random_bytes[0..4].try_into().unwrap());
Ok(random_number)
}
pub fn generate() -> Result<usize, String> {
let future = async_generate(); let result = futures::executor::block_on(future);
result
}
}
pub mod rng{
use std::ops::Rem;
use num_traits::{PrimInt, WrappingAdd, WrappingMul};
pub fn random_seed() -> usize {
let x = 42usize;
let y = &x as *const usize as usize;
let z = (y ^ 0xdeadbeef) + (y >> 3);
z
}
pub struct RandomNumberGenerator<T>
where
T: PrimInt + WrappingAdd + WrappingMul + Rem<Output = T>,
{
seed: T,
a: T, c: T, m: T, }
impl<T> RandomNumberGenerator<T>
where
T: PrimInt + WrappingAdd + WrappingMul + Rem<Output = T>,
{
pub fn new_custom(seed: T, a: T, c: T, m: T) -> Self {
RandomNumberGenerator { seed, a, c, m }
}
pub fn new() -> Self {
let a = T::from(1664525).unwrap();
let c = T::from(1013904223).unwrap();
let m = T::from(2u64.pow(32)).unwrap();
RandomNumberGenerator { seed: T::from(random_seed()).unwrap(), a, c, m }
}
pub fn next(&mut self) -> T {
self.seed = self.a.wrapping_mul(&self.seed).wrapping_add(&self.c) % self.m;
self.seed
}
pub fn range(&mut self, max: T) -> T {
self.next() % max
}
}
}