msg_tool\scripts\cat_system\archive/
twister.rs

1const STATE_LENGTH: usize = 624;
2const STATE_M: usize = 397;
3const MATRIX_A: u32 = 0x9908B0DF;
4const SIGN_MASK: u32 = 0x80000000;
5const LOWER_MASK: u32 = 0x7FFFFFFF;
6const TEMPERING_MASK_B: u32 = 0x9D2C5680;
7const TEMPERING_MASK_C: u32 = 0xEFC60000;
8const DEFAULT_SEED: u32 = 4357;
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, mut seed: u32) {
26        for i in 0..STATE_LENGTH {
27            let upper = seed & 0xffff0000;
28            seed = seed.wrapping_mul(69069).wrapping_add(1);
29            self.mt[i] = upper | ((seed & 0xffff0000) >> 16);
30            seed = seed.wrapping_mul(69069).wrapping_add(1);
31        }
32        self.mti = STATE_LENGTH;
33    }
34
35    pub fn rand(&mut self) -> u32 {
36        const MAG01: [u32; 2] = [0, MATRIX_A];
37
38        if self.mti >= STATE_LENGTH {
39            for kk in 0..(STATE_LENGTH - STATE_M) {
40                let y = (self.mt[kk] & SIGN_MASK) | (self.mt[kk + 1] & LOWER_MASK);
41                self.mt[kk] = self.mt[kk + STATE_M] ^ (y >> 1) ^ MAG01[(y & 1) as usize];
42            }
43            for kk in (STATE_LENGTH - STATE_M)..(STATE_LENGTH - 1) {
44                let y = (self.mt[kk] & SIGN_MASK) | (self.mt[kk + 1] & LOWER_MASK);
45                self.mt[kk] =
46                    self.mt[kk - (STATE_LENGTH - STATE_M)] ^ (y >> 1) ^ MAG01[(y & 1) as usize];
47            }
48            let y = (self.mt[STATE_LENGTH - 1] & SIGN_MASK) | (self.mt[0] & LOWER_MASK);
49            self.mt[STATE_LENGTH - 1] = self.mt[STATE_M - 1] ^ (y >> 1) ^ MAG01[(y & 1) as usize];
50
51            self.mti = 0;
52        }
53
54        let mut y = self.mt[self.mti];
55        self.mti += 1;
56
57        y ^= y >> 11;
58        y ^= (y << 7) & TEMPERING_MASK_B;
59        y ^= (y << 15) & TEMPERING_MASK_C;
60        y ^= y >> 18;
61
62        y
63    }
64}
65
66impl Default for MersenneTwister {
67    fn default() -> Self {
68        Self::new(DEFAULT_SEED)
69    }
70}