use rand::{thread_rng, Rng};
use std::fs;
use std::path::Path;
pub struct PwdGen;
impl PwdGen {
pub fn read_charset<P: AsRef<Path>>(path: P) -> Result<Vec<char>, std::io::Error> {
let contents = fs::read_to_string(path)?;
Ok(contents.trim().chars().collect())
}
pub fn random(len: usize, charset: &[char]) -> String {
let mut rng = thread_rng();
let random_password: String = (0..len)
.map(|_| {
let idx = rng.gen_range(0..charset.len());
charset[idx]
})
.collect();
random_password
}
pub fn add_padding(min_len: usize, max_len: usize, charset: &[char], password: String) -> String {
let mut rng = thread_rng();
let pad_len = rng.gen_range(min_len..=max_len);
let padding = PwdGen::random(pad_len, charset);
format!("P{:02}C{}{}", pad_len, padding, password)
}
pub fn strip_padding(padded: &str) -> Option<String> {
if !padded.starts_with('P') {
return Some(String::from(padded));
}
let c_index = padded.find('C')?;
let len_str = &padded[1..c_index];
let pad_len: usize = len_str.parse().ok()?;
let password_start = c_index + 1 + pad_len;
if padded.len() < password_start {
return None;
}
Some(padded[password_start..].to_string())
}
}