msg_tool\scripts\qlie\archive\pack/
twister.rs

1const 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}