1use std::sync::atomic::{AtomicI64, Ordering};
2use std::time::{UNIX_EPOCH, SystemTime};
3use std::num::Wrapping;
4use uuid::Uuid;
5
6
7const MULTIPLIER: Wrapping<i64> = Wrapping(0x5DEECE66D);
8const ADDEND: Wrapping<i64> = Wrapping(0xB);
9const MASK: Wrapping<i64> = Wrapping((1 << 48) - 1);
10
11const FLOAT_DIV: f32 = (1u32 << 24) as f32;
12const DOUBLE_DIV: f64 = (1u64 << 53) as f64;
13
14
15#[inline]
16pub fn initial_scramble(seed: i64) -> Wrapping<i64> {
17 (Wrapping(seed) ^ MULTIPLIER) & MASK
18}
19
20
21pub fn gen_seed() -> i64 {
23 static SEED: AtomicI64 = AtomicI64::new(8682522807148012);
24 let mut current = SEED.load(Ordering::Relaxed);
25 loop {
26 let next = current.wrapping_mul(181783497276652981);
27 match SEED.compare_exchange_weak(current, next, Ordering::Relaxed, Ordering::Relaxed) {
28 Ok(_) => {
29 return match SystemTime::now().duration_since(UNIX_EPOCH) {
34 Ok(d) => next ^ (d.as_nanos() as i64),
35 Err(_) => next
36 };
37 }
38 Err(old) => current = old
39 }
40 }
41}
42
43#[derive(Debug, Clone)]
44pub struct JavaRandom {
45 seed: Wrapping<i64>
46}
47
48impl JavaRandom {
49
50 #[inline]
51 pub fn new(seed: i64) -> JavaRandom {
52 JavaRandom { seed: initial_scramble(seed) }
53 }
54
55 #[inline]
56 pub fn new_seeded() -> JavaRandom {
57 Self::new(gen_seed())
58 }
59
60 #[inline]
61 pub fn new_blank() -> JavaRandom {
62 JavaRandom { seed: Wrapping(0) }
63 }
64
65 #[inline]
66 pub fn set_seed(&mut self, seed: i64) {
67 self.seed = initial_scramble(seed);
68 }
69
70 #[inline]
71 pub fn get_seed(&self) -> i64 {
72 self.seed.0
73 }
74
75 pub fn next_blank(&mut self) {
76 self.seed = (self.seed * MULTIPLIER + ADDEND) & MASK;
77 }
78
79 #[inline]
80 fn next(&mut self, bits: u8) -> i32 {
81 self.next_blank();
82 (self.seed.0 as u64 >> (48 - bits)) as i32
83 }
84
85 #[inline]
86 pub fn next_int(&mut self) -> i32 {
87 self.next(32)
88 }
89
90 pub fn next_int_bounded(&mut self, bound: i32) -> i32 {
91
92 if (bound & -bound) == bound {
93 (((bound as i64).wrapping_mul(self.next(31) as i64)) >> 31) as i32
94 } else {
95
96 let mut bits;
97 let mut val;
98
99 loop {
100 bits = self.next(31);
101 val = bits.rem_euclid(bound);
102 if bits - val + (bound - 1) >= 0 {
103 break;
104 }
105 }
106
107 val
108
109 }
110
111 }
112
113 pub fn next_long(&mut self) -> i64 {
114 ((self.next(32) as i64) << 32).wrapping_add(self.next(32) as i64)
115 }
116
117 pub fn next_float(&mut self) -> f32 {
118 self.next(24) as f32 / FLOAT_DIV
119 }
120
121 pub fn next_double(&mut self) -> f64 {
122 let high = (self.next(26) as i64) << 27;
123 let low = self.next(27) as i64;
124 (high.wrapping_add(low) as f64) / DOUBLE_DIV
125 }
126
127 pub fn next_insecure_uuid(&mut self) -> Uuid {
128 let most = (self.next_long() & -61441) | 16384;
129 let least = (self.next_long() & 4611686018427387903) | i64::MIN;
130 Uuid::from_u128((most as u128) << 64 | (least as u128))
131 }
132
133}