use rand::Rng;
mod charsets;
pub use charsets::*;
#[derive(Debug)]
pub struct PasswordGenerator {
charset: Vec<char>,
length: usize,
rng: rand::ThreadRng,
}
impl PasswordGenerator {
pub fn new(charset: Vec<char>, length: usize) -> Self {
PasswordGenerator { charset, length, rng: rand::thread_rng() }
}
#[inline]
pub fn length(mut self, length: usize) -> Self {
self.length = length;
self
}
#[inline]
pub fn generate(&mut self) -> String {
let mut s = String::with_capacity(self.length);
for _ in (0..self.length).into_iter() {
s.push(*self.rng.choose(&self.charset).unwrap());
}
s
}
#[inline]
pub fn generate_n(&mut self, n: usize) -> Vec<String> {
(0..n).into_iter().map(|_| self.generate()).collect()
}
#[inline]
pub fn combinations(&self) -> f64 {
(self.charset.len() as f64).powf(self.length as f64)
}
#[inline]
pub fn entropy(&self) -> usize {
self.combinations().log2().floor() as usize
}
}
impl std::convert::From<Vec<char>> for PasswordGenerator {
fn from(charset: Vec<char>) -> PasswordGenerator {
PasswordGenerator::new(charset, 20)
}
}
impl std::convert::From<&str> for PasswordGenerator {
fn from(charset: &str) -> PasswordGenerator {
PasswordGenerator::new((charset).chars().collect(), 20)
}
}