1
2
3pub mod true_rng{
4 use candid::Principal;
5 use ic_cdk::call;
6
7 pub async fn async_generate() -> Result<usize, String> {
8 let (random_bytes,): (Vec<u8>,) = call(Principal::management_canister(), "raw_rand", ()).await.map_err(|err| format!("{:?}", err))?;
9
10 const USIZE_SIZE: usize = std::mem::size_of::<usize>();
12 let mut padded_bytes = [0u8; std::mem::size_of::<usize>()];
13
14 let len = random_bytes.len().min(USIZE_SIZE);
15 padded_bytes[USIZE_SIZE - len..USIZE_SIZE].copy_from_slice(&random_bytes[0..len]);
16
17 let random_number = usize::from_be_bytes(padded_bytes);
18
19 Ok(random_number)
20 }
21
22 pub fn generate() -> Result<usize, String> {
23
24 let future = async_generate(); let result = futures::executor::block_on(future); result
28 }
29}
30
31pub mod rng{
32 use std::hash::{DefaultHasher, Hash, Hasher};
33 use std::ops::{Add, Mul, Rem};
34 use std::num::Wrapping;
35 use num_traits::{PrimInt, FromPrimitive, Unsigned, Bounded};
36
37 pub fn random_seed() -> usize {
38 let x = 42usize;
39 let y = &x as *const usize as usize;
40 let stack_value = &x as *const usize as usize;
41 let stack_value2 = &y as *const usize as usize;
42
43 let mut hasher = DefaultHasher::new();
45 stack_value.hash(&mut hasher);
46 stack_value2.hash(&mut hasher);
47 ic_cdk::api::time().hash(&mut hasher);
48 let hash = hasher.finish() as usize;
49
50 let mut seed = y ^ (hash << 7) ^ (stack_value >> 3);
52 seed = seed.wrapping_add(0x9e3779b9); seed = seed ^ (seed >> 31); seed = seed.wrapping_mul(0x85ebca6b); seed = seed ^ (seed >> 31); seed = seed.wrapping_mul(0xc2b2ae35); seed = seed ^ (seed >> 31); seed
60 }
61
62 pub struct RandomNumberGenerator<T>
63 where
64 T: PrimInt + FromPrimitive + Unsigned + Bounded + Mul<Output = T>,
65 {
66 seed: Wrapping<T>,
67 a: Wrapping<T>, c: Wrapping<T>, m: Wrapping<T>, }
71
72 impl<T> RandomNumberGenerator<T>
73 where
74 T: PrimInt + FromPrimitive + Unsigned + Bounded ,
75 Wrapping<T>: Mul<Output = Wrapping<T>> + Add<Output = Wrapping<T>> + Rem<Output = Wrapping<T>>
76
77 {
78 pub fn new_custom(seed: T, a: T, c: T, m: T) -> Self {
80 RandomNumberGenerator {
81 seed: Wrapping(seed),
82 a: Wrapping(a),
83 c: Wrapping(c),
84 m: Wrapping(m),
85 }
86 }
87
88 pub fn new() -> Self {
90 let (a, c, m) = Self::default_values();
91 RandomNumberGenerator {
92 seed: Wrapping(T::from(random_seed()).unwrap_or_else(T::min_value)),
93 a: Wrapping(a),
94 c: Wrapping(c),
95 m: Wrapping(m),
96 }
97 }
98
99 pub fn next(&mut self) -> T {
101 self.seed = (self.a * self.seed + self.c) % self.m;
102 self.seed.0
103 }
104
105 pub fn range(&mut self, max: T) -> T {
107 self.next() % max
108 }
109
110 fn default_values() -> (T, T, T) {
112 let bits = T::zero().count_zeros();
113 match bits {
114 8 => (
115 T::from(13).unwrap(), T::from(7).unwrap(),
117 T::from(31).unwrap(), ),
119 16 => (
120 T::from(25173).unwrap(), T::from(13849).unwrap(),
122 T::from(2u32.pow(16) - 1).unwrap(), ),
124 32 => (
125 T::from(1664525).unwrap(), T::from(1013904223).unwrap(),
127 T::from(2u64.pow(32) - 1).unwrap(), ),
129 _ => (
130 T::from(1664525).unwrap(), T::from(1013904223).unwrap(),
132 T::from(2u64.pow(32)).unwrap(),
133 )
134 }
135 }
136 }
137}