msg_tool\scripts\qlie\archive\pack/
twister.rs1const DEFAULT_SEED: u32 = 5489;
2const STATE_LENGTH: usize = 64;
3const STATE_M: usize = 39;
4const MATRIX_A: u32 = 0x9908B0DF;
5const SIGN_MASK: u32 = 0x80000000;
6const LOWER_MASK: u32 = 0x7FFFFFFF;
7const TEMPERING_MASK_B: u32 = 0x9C4F88E3;
8const TEMPERING_MASK_C: u32 = 0xE7F70000;
9
10pub struct MersenneTwister {
11 mt: [u32; STATE_LENGTH],
12 mti: usize,
13}
14
15impl MersenneTwister {
16 pub fn new(seed: u32) -> Self {
17 let mut twister = Self {
18 mt: [0; STATE_LENGTH],
19 mti: STATE_LENGTH,
20 };
21 twister.s_rand(seed);
22 twister
23 }
24
25 pub fn s_rand(&mut self, seed: u32) {
26 self.mt[0] = seed;
27 for i in 1..STATE_LENGTH {
28 self.mt[i] = (0x6611BC19u32.wrapping_mul(self.mt[i - 1] ^ (self.mt[i - 1] >> 30)))
29 .wrapping_add(i as u32);
30 }
31 }
32
33 pub fn xor_state(&mut self, hash: &[u8]) {
34 let length = (hash.len() / 4).min(STATE_LENGTH);
35 if length == 0 {
36 return;
37 }
38 for i in 0..length {
39 let part = u32::from_le_bytes([
40 hash[i * 4],
41 hash[i * 4 + 1],
42 hash[i * 4 + 2],
43 hash[i * 4 + 3],
44 ]);
45 self.mt[i] ^= part;
46 }
47 }
48
49 pub fn rand(&mut self) -> u32 {
50 const MAG01: [u32; 2] = [0, MATRIX_A];
51
52 if self.mti >= STATE_LENGTH {
53 for kk in 0..(STATE_LENGTH - STATE_M) {
54 let y = (self.mt[kk] & SIGN_MASK) | (self.mt[kk + 1] & LOWER_MASK) >> 1;
55 self.mt[kk] = self.mt[kk + STATE_M] ^ y ^ MAG01[(self.mt[kk + 1] & 1) as usize];
56 }
57 for kk in (STATE_LENGTH - STATE_M)..(STATE_LENGTH - 1) {
58 let y = (self.mt[kk] & SIGN_MASK) | (self.mt[kk + 1] & LOWER_MASK) >> 1;
59 self.mt[kk] = self.mt[kk - (STATE_LENGTH - STATE_M)]
60 ^ y
61 ^ MAG01[(self.mt[kk + 1] & 1) as usize];
62 }
63 let y = (self.mt[STATE_LENGTH - 1] & SIGN_MASK) | (self.mt[0] & LOWER_MASK) >> 1;
64 self.mt[STATE_LENGTH - 1] =
65 self.mt[STATE_M - 1] ^ y ^ MAG01[(self.mt[STATE_LENGTH - 2] & 1) as usize];
66
67 self.mti = 0;
68 }
69
70 let mut y = self.mt[self.mti];
71 self.mti += 1;
72
73 y ^= y >> 11;
74 y ^= (y << 7) & TEMPERING_MASK_B;
75 y ^= (y << 15) & TEMPERING_MASK_C;
76 y ^= y >> 18;
77
78 y
79 }
80
81 pub fn rand64(&mut self) -> u64 {
82 let low = self.rand() as u64;
83 let high = self.rand() as u64;
84 (high << 32) | low
85 }
86}