crypt_tool/
rng.rs

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
use std::ops::Range;
use std::time::SystemTime;

#[derive(Clone)]
pub struct LCG {
    a: u32,
    c: u32,
    m_mask: u32,
    seed: u32,
    state: u32,
}

impl LCG {
    fn from_state(state: u32) -> Self {
        let a: u32 = 1664525;
        let c: u32 = 1013904223;
        let m: u32 = 2u32 << 30;
        Self {
            a,
            c,
            m_mask: m - 1,
            seed: state,
            state,
        }
    }

    fn cal_state(seeds: &[u8]) -> u32 {
        seeds.iter().fold(0u32, |acc, &byte| {
            acc.wrapping_mul(31).wrapping_add(byte as u32)
        })
    }

    pub fn from_seed(seed: &[u8]) -> Self {
        Self::from_state(Self::cal_state(seed))
    }

    pub fn reset(&mut self) {
        self.state = self.seed;
    }

    pub fn generate(&mut self) -> u32 {
        self.state = (self.a.wrapping_mul(self.state).wrapping_add(self.c)) & self.m_mask;
        self.state
    }

    pub fn generate_u8(&mut self) -> u8 {
        (self.generate() % 256) as u8
    }

    pub fn rand_range(&mut self, range: Range<usize>) -> usize {
        let Range { start, end } = range;
        (self.generate() as usize) % (end - start) + start
    }

    pub fn generate_random_string(&mut self, len: usize) -> String {
        const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

        (0..len)
            .map(|_| CHARSET[self.rand_range(0..CHARSET.len())] as char)
            .collect::<String>()
    }
}

pub fn system_random() -> u32 {
    // 根据系统时间来生成随机数
    let now = SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .map(|d| d.as_nanos() % u32::MAX as u128)
        .unwrap_or(0) as u32;

    let mut rnd = LCG::from_state(now);

    rnd.generate()
}