Updated password generation functions

This commit is contained in:
StNicolay 2023-06-04 19:54:39 +03:00
parent 3b2633c880
commit 4d4cec1353
Signed by: StNicolay
GPG Key ID: 9693D04DCD962B0D

View File

@ -1,6 +1,6 @@
use arrayvec::{ArrayString, ArrayVec}; use arrayvec::ArrayString;
use rand::{rngs::OsRng, seq::SliceRandom}; use rand::{rngs::OsRng, seq::SliceRandom};
use std::str::from_utf8_unchecked; use std::array;
const CHARS: &[u8] = br##"!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~"##; const CHARS: &[u8] = br##"!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~"##;
@ -16,7 +16,7 @@ bitflags::bitflags! {
/// Returns true if the generated master password is valid. /// Returns true if the generated master password is valid.
/// It checks that it has at least one lowercase, one uppercase, one number and one punctuation char /// It checks that it has at least one lowercase, one uppercase, one number and one punctuation char
#[inline] #[inline]
fn check_generated_password(password: &[u8]) -> bool { fn check_generated_password(password: &[u8; 32]) -> bool {
let mut flags = PasswordFlags::empty(); let mut flags = PasswordFlags::empty();
for &byte in password { for &byte in password {
match byte { match byte {
@ -35,19 +35,18 @@ fn check_generated_password(password: &[u8]) -> bool {
false false
} }
#[inline]
fn generate_password() -> ArrayString<32> {
loop {
let password: [u8; 32] = array::from_fn(|_| *CHARS.choose(&mut OsRng).unwrap());
if check_generated_password(&password) {
return ArrayString::from_byte_string(&password).unwrap();
}
}
}
/// Continuously generates the password until it passes the checks /// Continuously generates the password until it passes the checks
#[inline] #[inline]
pub fn generate_passwords() -> [ArrayString<32>; 10] { pub fn generate_passwords() -> [ArrayString<32>; 10] {
let mut passwords = ArrayVec::new_const(); array::from_fn(|_| generate_password())
while !passwords.is_full() {
let password: ArrayVec<u8, 32> = (0..32)
.map(|_| *CHARS.choose(&mut OsRng).unwrap())
.collect();
if check_generated_password(&password) {
let mut string = ArrayString::<32>::new_const();
unsafe { string.push_str(from_utf8_unchecked(&password)) };
passwords.push(string)
}
}
unsafe { passwords.into_inner_unchecked() }
} }