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