passgenlib/
gen_engine.rs

1pub mod gen_engine {
2    use crate::Passgen;
3    use rand::{Rng, SeedableRng};
4    use rand_hc::Hc128Rng;
5    use rand_isaac::Isaac64Rng;
6
7    // Letters charset.
8    pub const LETTERS_CHARSET: &str = "abcdefghijklmnopqrstuvwxyz";
9    // Capital letters charset.
10    pub const U_LETTERS_CHARSET: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
11    // Numeric charset.
12    pub const NUM_CHARSET: &str = "0123456789";
13    // Special symbols charset.
14    pub const SPEC_SYMB_CHARSET: &str = ")([]{}*&^%$#@!~";
15    // Simple special charset without inconvenient symbols.
16    pub const SIMP_SYMB_CHARSET: &str = "*&%$#@!";
17    // Strong & usability charset.
18    // Set without ambiguous and inconvenient letters with numbers.
19    pub const STRONG_USAB_CHARSET: &str = "ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789";
20    // Strong & usability letters charset.
21    // Set without ambiguous and inconvenient letters.
22    pub const STRONG_USAB_LETTERS_CHARSET: &str = "ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz";
23
24    impl Passgen {
25        pub(crate) fn generate_pass(&mut self, res_len: u32) -> String {
26            let mut isaac_seeder = Isaac64Rng::from_os_rng();
27            let mut rng = Hc128Rng::from_rng(&mut isaac_seeder);
28            let mut pass_assembly: Vec<char> = Vec::new();
29
30            if self.custom_charset.len() != 0 {
31                let mut cc_vec: Vec<char> = self.custom_charset.chars().into_iter().collect();
32                pass_assembly.append(&mut cc_vec);
33            } else if self.enab_strong_usab
34                || (!self.enab_letters
35                    && !self.enab_u_letters
36                    && !self.enab_num
37                    && !self.enab_spec_symbs)
38            {
39                let mut suc_vec: Vec<char> = STRONG_USAB_CHARSET.chars().into_iter().collect();
40                    pass_assembly.append(&mut suc_vec);
41            } else {
42                if self.enab_letters {
43                    let mut el_vec: Vec<char> = LETTERS_CHARSET.chars().into_iter().collect();
44                    pass_assembly.append(&mut el_vec);
45                }
46                if self.enab_u_letters {
47                    let mut eul_vec: Vec<char> = U_LETTERS_CHARSET.chars().into_iter().collect();
48                    pass_assembly.append(&mut eul_vec);
49                }
50                if self.enab_num {
51                    let mut en_vec: Vec<char> = NUM_CHARSET.chars().into_iter().collect();
52                    pass_assembly.append(&mut en_vec);
53                }
54                if self.enab_spec_symbs {
55                    let mut ess_vec: Vec<char> = SPEC_SYMB_CHARSET.chars().into_iter().collect();
56                    pass_assembly.append(&mut ess_vec);
57                }
58            }
59
60            let mut pass_candidate_vec: Vec<char> = Vec::new();
61
62            if self.enab_strong_usab {
63                let letters_charset: Vec<char> =
64                    STRONG_USAB_LETTERS_CHARSET.chars().into_iter().collect();
65                let simp_symb_charset: Vec<char> = SIMP_SYMB_CHARSET.chars().into_iter().collect();
66
67                // gen first pass symbol from all letters
68                pass_candidate_vec.push(letters_charset[rng.random_range(0..letters_charset.len())]);
69
70                // gen main pass body
71                for _ in 0..(res_len - 2) {
72                    pass_candidate_vec.push(pass_assembly[rng.random_range(0..pass_assembly.len())]);
73                }
74
75                // gen last pass symbol from simple symbols
76                pass_candidate_vec
77                    .push(simp_symb_charset[rng.random_range(0..simp_symb_charset.len())]);
78            } else {
79                pass_candidate_vec = (0..res_len)
80                    .map(|_| pass_assembly[rng.random_range(0..pass_assembly.len())])
81                    .collect();
82            }
83            String::from_iter(pass_candidate_vec)
84        }
85    }
86}