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
|
use chbs::scheme::ToScheme as _;
use rand::seq::SliceRandom as _;
const SYMBOLS: &[u8] = b"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
const NUMBERS: &[u8] = b"0123456789";
const LETTERS: &[u8] =
b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const NONCONFUSABLES: &[u8] = b"34678abcdefhjkmnpqrtuwxy";
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum Type {
AllChars,
NoSymbols,
Numbers,
NonConfusables,
Diceware,
}
pub fn pwgen(ty: Type, len: usize) -> String {
if ty == Type::Diceware {
let mut config = chbs::config::BasicConfig::default();
config.words = len;
config.capitalize_first = chbs::probability::Probability::Never;
config.capitalize_words = chbs::probability::Probability::Never;
return config.to_scheme().generate();
}
let alphabet = match ty {
Type::AllChars => {
let mut v = vec![];
v.extend(SYMBOLS.iter().copied());
v.extend(NUMBERS.iter().copied());
v.extend(LETTERS.iter().copied());
v
}
Type::NoSymbols => {
let mut v = vec![];
v.extend(NUMBERS.iter().copied());
v.extend(LETTERS.iter().copied());
v
}
Type::Numbers => {
let mut v = vec![];
v.extend(NUMBERS.iter().copied());
v
}
Type::NonConfusables => {
let mut v = vec![];
v.extend(NONCONFUSABLES.iter().copied());
v
}
Type::Diceware => unreachable!(),
};
let mut rng = rand::thread_rng();
let mut pass = vec![];
pass.extend(alphabet.choose_multiple(&mut rng, len).copied());
// unwrap is safe because the method of generating passwords guarantees
// valid utf8
String::from_utf8(pass).unwrap()
}
|