Update and list rule sets if one is not specified
This commit is contained in:
parent
9cf0759b7a
commit
8816e30252
3 changed files with 175 additions and 150 deletions
167
Cargo.lock
generated
167
Cargo.lock
generated
|
|
@ -1,57 +1,36 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.11"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
|
||||
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.151"
|
||||
version = "0.2.174"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||
|
||||
[[package]]
|
||||
name = "password-gen"
|
||||
|
|
@ -64,44 +43,52 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.70"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
|
||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
name = "r-efi"
|
||||
version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
|
|
@ -109,27 +96,27 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.193"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
|
||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.193"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -138,18 +125,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.4"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80"
|
||||
checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.41"
|
||||
version = "2.0.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269"
|
||||
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -158,63 +145,81 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.8"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35"
|
||||
checksum = "ed0aee96c12fa71097902e0bb061a5e1ebd766a6636bb605ba401c45c1650eac"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit",
|
||||
"toml_parser",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.5"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||
checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.21.0"
|
||||
name = "toml_parser"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03"
|
||||
checksum = "97200572db069e74c512a14117b296ba0a80a30123fbbb5aa1f4a348f639ca30"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
version = "0.14.2+wasi-0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
|
||||
dependencies = [
|
||||
"wit-bindgen-rt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.30"
|
||||
version = "0.7.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b5c3db89721d50d0e2a673f5043fc4722f76dcc352d7b1ab8b8288bed4ed2c5"
|
||||
checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.39.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[patch.unused]]
|
||||
name = "brisk"
|
||||
version = "0.1.0"
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[patch.unused]]
|
||||
name = "how"
|
||||
version = "0.3.0"
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
|
|
|||
10
Cargo.toml
10
Cargo.toml
|
|
@ -1,11 +1,9 @@
|
|||
[package]
|
||||
name = "password-gen"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
rand = "0.8.5"
|
||||
serde = { version = "1.0.193", features = ["derive"] }
|
||||
toml = { version = "0.8.8", default-features = false, features = ["parse"] }
|
||||
rand = { version = "0.9", default-features = false, features = ["alloc", "os_rng", "std_rng"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
toml = { version = "0.9", default-features = false, features = ["parse", "serde"] }
|
||||
|
|
|
|||
148
src/main.rs
148
src/main.rs
|
|
@ -4,81 +4,103 @@
|
|||
extern crate serde;
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::process::ExitCode;
|
||||
|
||||
use rand::Rng;
|
||||
use rand::distributions::Slice as SliceDist;
|
||||
use rand::distr::SampleString;
|
||||
use rand::distr::slice::Choose;
|
||||
use rand::{Rng, SeedableRng};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum RuleSet {
|
||||
Password {
|
||||
length: usize,
|
||||
lowercase: bool,
|
||||
uppercase: bool,
|
||||
numbers: bool,
|
||||
#[serde(default = "default_special_characters")]
|
||||
special_characters: Vec<char>,
|
||||
},
|
||||
Passphrase {
|
||||
count: usize,
|
||||
delimiters: Vec<char>,
|
||||
/// Path to words list.
|
||||
words: String,
|
||||
},
|
||||
Password {
|
||||
length: usize,
|
||||
lowercase: bool,
|
||||
uppercase: bool,
|
||||
numbers: bool,
|
||||
#[serde(default = "default_special_characters")]
|
||||
special_characters: Vec<char>,
|
||||
},
|
||||
Passphrase {
|
||||
count: usize,
|
||||
delimiters: Vec<char>,
|
||||
/// Path to words list.
|
||||
words: String,
|
||||
},
|
||||
}
|
||||
|
||||
fn default_special_characters() -> Vec<char> {
|
||||
(0..128)
|
||||
.map(|b| char::from_u32(b).unwrap())
|
||||
.filter(|c| c.is_ascii_graphic() && !c.is_ascii_alphanumeric())
|
||||
.collect()
|
||||
(0..128)
|
||||
.map(|b| char::from_u32(b).unwrap())
|
||||
.filter(|c| c.is_ascii_graphic() && !c.is_ascii_alphanumeric())
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut rng = rand::thread_rng();
|
||||
fn main() -> ExitCode {
|
||||
let mut rng = rand::rngs::StdRng::from_os_rng();
|
||||
|
||||
let mut rule_sets: HashMap<String, RuleSet> = toml::from_str(&std::fs::read_to_string("rules.toml").unwrap()).unwrap();
|
||||
let mut rule_sets: HashMap<String, RuleSet> =
|
||||
toml::from_str(&std::fs::read_to_string("rules.toml").unwrap()).unwrap();
|
||||
|
||||
let mut args = std::env::args();
|
||||
_ = args.next().unwrap();
|
||||
let rule_set_name = args.next().expect("Must specify a rule set name");
|
||||
let mut args = std::env::args();
|
||||
_ = args.next().unwrap();
|
||||
let Some(rule_set_name) = args.next() else {
|
||||
println!("Must specify a rule set name:");
|
||||
for name in rule_sets.into_keys() {
|
||||
println!(" {}", name);
|
||||
}
|
||||
return ExitCode::FAILURE;
|
||||
};
|
||||
|
||||
let password = match rule_sets.remove(&rule_set_name).unwrap() {
|
||||
RuleSet::Password { length, lowercase, uppercase, numbers, special_characters } => {
|
||||
let mut chars = HashSet::new();
|
||||
if lowercase {
|
||||
chars.extend('a'..='z');
|
||||
}
|
||||
if uppercase {
|
||||
chars.extend('A'..='Z');
|
||||
}
|
||||
if numbers {
|
||||
chars.extend('0'..='9');
|
||||
}
|
||||
chars.extend(&special_characters);
|
||||
let chars = chars.into_iter().collect::<Vec<_>>();
|
||||
let password = match rule_sets.remove(&rule_set_name).unwrap() {
|
||||
RuleSet::Password {
|
||||
length,
|
||||
lowercase,
|
||||
uppercase,
|
||||
numbers,
|
||||
special_characters,
|
||||
} => {
|
||||
let mut chars = HashSet::new();
|
||||
if lowercase {
|
||||
chars.extend('a'..='z');
|
||||
}
|
||||
if uppercase {
|
||||
chars.extend('A'..='Z');
|
||||
}
|
||||
if numbers {
|
||||
chars.extend('0'..='9');
|
||||
}
|
||||
chars.extend(&special_characters);
|
||||
let chars = chars.into_iter().collect::<Vec<_>>();
|
||||
|
||||
rng.sample_iter(SliceDist::new(&chars).unwrap())
|
||||
.take(length)
|
||||
.collect::<String>()
|
||||
}
|
||||
RuleSet::Passphrase { count, delimiters, words } => {
|
||||
assert!(count > 0);
|
||||
let words = std::fs::read_to_string(&words).unwrap();
|
||||
let words = words.lines().filter(|s| !s.is_empty()).collect::<Vec<_>>();
|
||||
let words = SliceDist::new(&words).unwrap();
|
||||
let delimiters = delimiters.iter().map(char::to_string).collect::<Vec<String>>();
|
||||
let delimiters = SliceDist::new(&delimiters).unwrap();
|
||||
let mut s = String::new();
|
||||
let mut word = rng.sample(&words);
|
||||
for _ in 0..count-1 {
|
||||
s.push_str(word);
|
||||
word = rng.sample(&words);
|
||||
s.push_str(rng.sample(&delimiters));
|
||||
}
|
||||
s.push_str(word);
|
||||
s
|
||||
}
|
||||
};
|
||||
println!("{}", password);
|
||||
Choose::new(&chars).unwrap().sample_string(&mut rng, length)
|
||||
}
|
||||
RuleSet::Passphrase {
|
||||
count,
|
||||
delimiters,
|
||||
words,
|
||||
} => {
|
||||
assert!(count > 0);
|
||||
let words = std::fs::read_to_string(&words).unwrap();
|
||||
let words = words.lines().filter(|s| !s.is_empty()).collect::<Vec<_>>();
|
||||
let words = Choose::new(&words).unwrap();
|
||||
let delimiters = delimiters
|
||||
.iter()
|
||||
.map(char::to_string)
|
||||
.collect::<Vec<String>>();
|
||||
let delimiters = Choose::new(&delimiters).unwrap();
|
||||
let mut s = String::new();
|
||||
let mut word = rng.sample(&words);
|
||||
for _ in 0..count - 1 {
|
||||
s.push_str(word);
|
||||
word = rng.sample(&words);
|
||||
s.push_str(rng.sample(&delimiters));
|
||||
}
|
||||
s.push_str(word);
|
||||
s
|
||||
}
|
||||
};
|
||||
println!("{}", password);
|
||||
|
||||
ExitCode::SUCCESS
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue