From 62adf34f3abbbfda751e0423132b913ebf2dc7c3 Mon Sep 17 00:00:00 2001 From: kostDev Date: Sun, 3 Nov 2024 22:46:51 +0200 Subject: [PATCH 1/8] new UTF-8 symbols & optimisations --- src/main.rs | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/main.rs b/src/main.rs index a2e5e2a..b188055 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,21 +1,28 @@ -use rand::{Rng,seq::SliceRandom, thread_rng}; +use rand::{seq::{SliceRandom, IteratorRandom}, thread_rng}; use std::iter::repeat_with; use std::io::{stdout, stdin, Write}; const LOW_CASE: &str = "abcdefghijklmnopqrstuvwxyz"; const UP_CASE: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; -const SYMBOLS: &str = "#$%^*_-=+~;[<{(:&|@:)}>];~.?!"; const NUMBERS: &str = "0123456789"; +const SYMBOLS: &str = "#$%^*_-=+~;[<{(:&|@:)}>];~.?!"; +const ARROWS: &str = "→←↑↓↔↕↩↪"; +const MATH_SYMBOLS: &str = "∑∆∞∫∏√≠≈±∂"; +const MOOD_SYMBOLS: &str = "😁😇🙂🙃🥳🤠😎"; + const DEFAULT_ARGS: [&str;4] = ["a", "aa", "s", "n"]; fn generate_line(args: &[&str]) -> String { let mut rng = thread_rng(); let mut list = args.iter().map(|&x| match x { - "a" => LOW_CASE, - "aa" => UP_CASE, - "s" => SYMBOLS, - "n" => NUMBERS, + "a" | "lower" => LOW_CASE, + "aa" | "upper" => UP_CASE, + "n" | "number" => NUMBERS, + "s" | "symbols" => SYMBOLS, + "r" | "arrows" => ARROWS, + "m" | "math" => MATH_SYMBOLS, + "mm" | "mood" => MOOD_SYMBOLS, custom => custom, }).collect::>(); @@ -25,7 +32,7 @@ fn generate_line(args: &[&str]) -> String { fn generate_pass(line: &str, max: usize) -> String { let mut rng = thread_rng(); - repeat_with(|| { line.chars().nth(rng.gen_range(0..line.len())).unwrap() }) + repeat_with(|| line.chars().choose(&mut rng).unwrap()) .take(max) .collect() } @@ -38,8 +45,8 @@ fn main() { let input_items = input.split_whitespace().collect::>(); - if input_items.len().eq(&0usize) { - eprintln!("Empty input!"); + if input_items.is_empty() { + eprintln!("Empty input! Please provide a password length or/and optional character sets."); return; } // first arg always number @@ -47,13 +54,9 @@ fn main() { .expect("invalid value for password length!"); let args = &input_items[1..]; - let line = match &args.len() { - 0 => generate_line(&DEFAULT_ARGS), // default - _ => generate_line(&args), // custom [ .., .., ... ] - }; + let line = generate_line(if args.is_empty() { &DEFAULT_ARGS } else { args }); let password = generate_pass(&line, password_len); println!("Yours generated password[{password_len}]: {password}"); // println!("Unique generated line: {}", new_line); - } From 9d8d4b085c763ae455b6fd940c2bdf173903ca06 Mon Sep 17 00:00:00 2001 From: kostDev Date: Sun, 3 Nov 2024 22:55:03 +0200 Subject: [PATCH 2/8] test new UTF-8 Domino Tiles --- src/main.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.rs b/src/main.rs index b188055..c301c45 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ const SYMBOLS: &str = "#$%^*_-=+~;[<{(:&|@:)}>];~.?!"; const ARROWS: &str = "→←↑↓↔↕↩↪"; const MATH_SYMBOLS: &str = "∑∆∞∫∏√≠≈±∂"; const MOOD_SYMBOLS: &str = "😁😇🙂🙃🥳🤠😎"; +// const DOMI_SYMBOLS: &str = "🁣🁫🁳🁻🂃🂋🂓"; const DEFAULT_ARGS: [&str;4] = ["a", "aa", "s", "n"]; @@ -23,6 +24,7 @@ fn generate_line(args: &[&str]) -> String { "r" | "arrows" => ARROWS, "m" | "math" => MATH_SYMBOLS, "mm" | "mood" => MOOD_SYMBOLS, + // "dm" | "domi" => DOMI_SYMBOLS, custom => custom, }).collect::>(); From 329f82ef4503d3fc4adb981f9c39dfd334c20883 Mon Sep 17 00:00:00 2001 From: kostDev Date: Sun, 3 Nov 2024 23:13:32 +0200 Subject: [PATCH 3/8] refactoring fns --- src/main.rs | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index c301c45..ace0619 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,12 +9,35 @@ const SYMBOLS: &str = "#$%^*_-=+~;[<{(:&|@:)}>];~.?!"; const ARROWS: &str = "→←↑↓↔↕↩↪"; const MATH_SYMBOLS: &str = "∑∆∞∫∏√≠≈±∂"; const MOOD_SYMBOLS: &str = "😁😇🙂🙃🥳🤠😎"; -// const DOMI_SYMBOLS: &str = "🁣🁫🁳🁻🂃🂋🂓"; const DEFAULT_ARGS: [&str;4] = ["a", "aa", "s", "n"]; -fn generate_line(args: &[&str]) -> String { +fn dfm() { + println!( + "\n╔════════════════════════════════════════════════════╗\n\ + ║ Available Symbols for Password Generation ║\n\ + ╠════════════════════════════════════════════════════╣\n\ + ║ a or lowercase → abcdefghijklmnopqrstuvwxyz ║\n\ + ║ aa or uppercase → ABCDEFGHIJKLMNOPQRSTUVWXYZ ║\n\ + ║ n or number → 0123456789: ║\n\ + ║ s or symbols → #$%^*_-=+~;[<(:&|@:)>];~.?! ║\n\ + ║ r or arrows → →←↑↓↔↕↩↪ ║\n\ + ║ m or math → ∑∆∞∫∏√≠≈±∂ ║\n\ + ║ mm or mood → 😁😇🙂🙃🥳🤠😎 ║\n\ + ╠════════════════════════════════════════════════════╣\n\ + ║ Examples: ║\n\ + ║ - Lowercase and uppercase letters: a aa ║\n\ + ║ - Numbers and special symbols: n s ║\n\ + ║ - Math and mood symbols: m mm ║\n\ + ╠════════════════════════════════════════════════════╣\n\ + ║ You can combine these options to create complex ║\n\ + ║ passwords! ║\n\ + ╚════════════════════════════════════════════════════╝\n" + ); +} + +fn generate_chars_pool(args: &[&str]) -> String { let mut rng = thread_rng(); let mut list = args.iter().map(|&x| match x { "a" | "lower" => LOW_CASE, @@ -24,7 +47,6 @@ fn generate_line(args: &[&str]) -> String { "r" | "arrows" => ARROWS, "m" | "math" => MATH_SYMBOLS, "mm" | "mood" => MOOD_SYMBOLS, - // "dm" | "domi" => DOMI_SYMBOLS, custom => custom, }).collect::>(); @@ -32,14 +54,13 @@ fn generate_line(args: &[&str]) -> String { list.concat() } -fn generate_pass(line: &str, max: usize) -> String { +fn create_password(pool: &str, n: usize) -> String { let mut rng = thread_rng(); - repeat_with(|| line.chars().choose(&mut rng).unwrap()) - .take(max) - .collect() + repeat_with(|| pool.chars().choose(&mut rng).unwrap()).take(n).collect() } fn main() { + //dfm(); let mut input: String = String::new(); print!(">> "); stdout().flush().unwrap(); @@ -56,8 +77,8 @@ fn main() { .expect("invalid value for password length!"); let args = &input_items[1..]; - let line = generate_line(if args.is_empty() { &DEFAULT_ARGS } else { args }); - let password = generate_pass(&line, password_len); + let line = generate_chars_pool(if args.is_empty() { &DEFAULT_ARGS } else { args }); + let password = create_password(&line, password_len); println!("Yours generated password[{password_len}]: {password}"); // println!("Unique generated line: {}", new_line); From d64d7239ae1fefff033f223fbb3460bff0484805 Mon Sep 17 00:00:00 2001 From: kostDev Date: Sun, 3 Nov 2024 23:39:31 +0200 Subject: [PATCH 4/8] refactoring fns --- src/main.rs | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/main.rs b/src/main.rs index ace0619..ff87440 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,12 +37,11 @@ fn dfm() { ); } -fn generate_chars_pool(args: &[&str]) -> String { - let mut rng = thread_rng(); +fn create_ch_pool(args: &[&str]) -> String { let mut list = args.iter().map(|&x| match x { "a" | "lower" => LOW_CASE, "aa" | "upper" => UP_CASE, - "n" | "number" => NUMBERS, + "n" | "nums" => NUMBERS, "s" | "symbols" => SYMBOLS, "r" | "arrows" => ARROWS, "m" | "math" => MATH_SYMBOLS, @@ -50,13 +49,14 @@ fn generate_chars_pool(args: &[&str]) -> String { custom => custom, }).collect::>(); - list.shuffle(&mut rng); + list.shuffle(&mut thread_rng()); list.concat() } fn create_password(pool: &str, n: usize) -> String { let mut rng = thread_rng(); - repeat_with(|| pool.chars().choose(&mut rng).unwrap()).take(n).collect() + repeat_with(|| pool.chars().choose(&mut rng).unwrap()) + .take(n).collect() } fn main() { @@ -66,20 +66,18 @@ fn main() { stdout().flush().unwrap(); stdin().read_line(&mut input).unwrap(); - let input_items = input.split_whitespace().collect::>(); + let tokens = input.split_whitespace().collect::>(); - if input_items.is_empty() { - eprintln!("Empty input! Please provide a password length or/and optional character sets."); + if tokens.is_empty() { + eprintln!("Empty input! Please provide a password length or/and optional character set!"); return; } - // first arg always number - let password_len = input_items[0].parse::() - .expect("invalid value for password length!"); - - let args = &input_items[1..]; - let line = generate_chars_pool(if args.is_empty() { &DEFAULT_ARGS } else { args }); - let password = create_password(&line, password_len); + // first arg always number as password length + let lens = tokens[0].parse::().expect("Invalid value for password length!"); + let args = &tokens[1..]; + let pool = create_ch_pool(if args.is_empty() { &DEFAULT_ARGS } else { args }); + let password = create_password(&pool, lens); - println!("Yours generated password[{password_len}]: {password}"); - // println!("Unique generated line: {}", new_line); + println!("Yours generated password[{lens}]: {password}"); + // println!("Unique pool: {}", pool); } From 0fbfaed8324ded2cfd50b75d96703c34daeb0e21 Mon Sep 17 00:00:00 2001 From: kostDev Date: Mon, 4 Nov 2024 00:45:07 +0200 Subject: [PATCH 5/8] refactoring project --- Cargo.toml | 8 ++++++++ src/cli.rs | 12 ++++++++++++ src/consts.rs | 13 +++++++++++++ src/info.rs | 25 +++++++++++++++++++++++++ src/lib.rs | 3 +++ src/main.rs | 49 ++++++++++--------------------------------------- 6 files changed, 71 insertions(+), 39 deletions(-) create mode 100644 src/cli.rs create mode 100644 src/consts.rs create mode 100644 src/info.rs create mode 100644 src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index c1dac7c..4f6768f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,14 @@ description = "A simple utility to generate random passwords based on a user-spe repository = "https://github.com/kostDev/genpass" readme = "README.md" +[lib] +name = "genpass" +path = "src/lib.rs" + +[[bin]] +name = "genpass" +path = "src/main.rs" + [dependencies] rand = "0.8.5" diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 0000000..d4e86e6 --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,12 @@ +use super::info::display_help; +use super::consts::CMD_HELP; +use std::process::exit; + +pub fn handle_cli() { + let _args: Vec = std::env::args().collect(); + + if _args.contains(&CMD_HELP.to_string()) { + display_help(); + exit(0); + } +} diff --git a/src/consts.rs b/src/consts.rs new file mode 100644 index 0000000..8d622e0 --- /dev/null +++ b/src/consts.rs @@ -0,0 +1,13 @@ +// ALL Characters +pub const LOW_CASE: &str = "abcdefghijklmnopqrstuvwxyz"; +pub const UP_CASE: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +pub const NUMBERS: &str = "0123456789"; +pub const SYMBOLS: &str = "#$%^*_-=+~;[<{(:&|@:)}>];~.?!"; +pub const ARROWS: &str = "→←↑↓↔↕↩↪"; +pub const MATH_SYMBOLS: &str = "∑∆∞∫∏√≠≈±∂"; +pub const MOOD_SYMBOLS: &str = "😁😇🙂🙃🥳🤠😎"; +// -------------------------- +pub const DEFAULT_ARGS: [&str;4] = ["a", "aa", "s", "n"]; +// -------------------------- +// Command +pub const CMD_HELP: &str = "-help"; diff --git a/src/info.rs b/src/info.rs new file mode 100644 index 0000000..0f98b1c --- /dev/null +++ b/src/info.rs @@ -0,0 +1,25 @@ + +pub fn display_help() { + println!("═════════════════════════════════════════════════════════════"); + println!(" Password Generator Help "); + println!("═════════════════════════════════════════════════════════════"); + println!(" Use the following options to customize your password: "); + println!(" ┌───────────────┬───────────────────────────────────────┐"); + println!(" │ Option │ Description │"); + println!(" ├───────────────┼───────────────────────────────────────┤"); + println!(" │ a │ Lowercase letters (a-z) │"); + println!(" │ aa │ Uppercase letters (A-Z) │"); + println!(" │ n │ Numbers [0-9] │"); + println!(" │ s │ Symbols (e.g., @, #, %, &, etc.) │"); + println!(" │ r │ Arrows (→, ←, ↑, ↓, etc.) │"); + println!(" │ m │ Math symbols (e.g., ∑, ∆, ∞) │"); + println!(" │ mm │ Mood symbols (e.g., 😁, 🙂, 🙃) │"); + println!(" │ custom │ Custom string of characters │"); + println!(" └───────────────┴───────────────────────────────────────┘"); + println!(" Example usage:"); + println!(" genpass 16 a n s -> Generates a 16-char password with lowercase, numbers, and symbols."); + println!(" genpass 12 a aa n -> Generates a 12-char password with lowercase, uppercase, and numbers."); + println!(" genpass 20 m mm -> Generates a 20-char password with math and mood symbols."); + println!(" genpass 8 ^@_@^ -> Generates an 8-char password from your custom character set."); + println!("═════════════════════════════════════════════════════════════"); +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..3692cec --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,3 @@ +pub mod cli; +pub mod info; +pub mod consts; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index ff87440..c0d9a3c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,44 +1,14 @@ use rand::{seq::{SliceRandom, IteratorRandom}, thread_rng}; -use std::iter::repeat_with; use std::io::{stdout, stdin, Write}; +use std::iter::repeat_with; +use genpass::consts::{ + LOW_CASE, UP_CASE, NUMBERS, SYMBOLS, ARROWS, MATH_SYMBOLS, MOOD_SYMBOLS, DEFAULT_ARGS +}; +use genpass::{ cli::handle_cli }; -const LOW_CASE: &str = "abcdefghijklmnopqrstuvwxyz"; -const UP_CASE: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; -const NUMBERS: &str = "0123456789"; -const SYMBOLS: &str = "#$%^*_-=+~;[<{(:&|@:)}>];~.?!"; -const ARROWS: &str = "→←↑↓↔↕↩↪"; -const MATH_SYMBOLS: &str = "∑∆∞∫∏√≠≈±∂"; -const MOOD_SYMBOLS: &str = "😁😇🙂🙃🥳🤠😎"; - - -const DEFAULT_ARGS: [&str;4] = ["a", "aa", "s", "n"]; - -fn dfm() { - println!( - "\n╔════════════════════════════════════════════════════╗\n\ - ║ Available Symbols for Password Generation ║\n\ - ╠════════════════════════════════════════════════════╣\n\ - ║ a or lowercase → abcdefghijklmnopqrstuvwxyz ║\n\ - ║ aa or uppercase → ABCDEFGHIJKLMNOPQRSTUVWXYZ ║\n\ - ║ n or number → 0123456789: ║\n\ - ║ s or symbols → #$%^*_-=+~;[<(:&|@:)>];~.?! ║\n\ - ║ r or arrows → →←↑↓↔↕↩↪ ║\n\ - ║ m or math → ∑∆∞∫∏√≠≈±∂ ║\n\ - ║ mm or mood → 😁😇🙂🙃🥳🤠😎 ║\n\ - ╠════════════════════════════════════════════════════╣\n\ - ║ Examples: ║\n\ - ║ - Lowercase and uppercase letters: a aa ║\n\ - ║ - Numbers and special symbols: n s ║\n\ - ║ - Math and mood symbols: m mm ║\n\ - ╠════════════════════════════════════════════════════╣\n\ - ║ You can combine these options to create complex ║\n\ - ║ passwords! ║\n\ - ╚════════════════════════════════════════════════════╝\n" - ); -} fn create_ch_pool(args: &[&str]) -> String { - let mut list = args.iter().map(|&x| match x { + let mut pool = args.iter().map(|&x| match x { "a" | "lower" => LOW_CASE, "aa" | "upper" => UP_CASE, "n" | "nums" => NUMBERS, @@ -49,8 +19,8 @@ fn create_ch_pool(args: &[&str]) -> String { custom => custom, }).collect::>(); - list.shuffle(&mut thread_rng()); - list.concat() + pool.shuffle(&mut thread_rng()); + pool.concat() } fn create_password(pool: &str, n: usize) -> String { @@ -60,7 +30,8 @@ fn create_password(pool: &str, n: usize) -> String { } fn main() { - //dfm(); + handle_cli(); + let mut input: String = String::new(); print!(">> "); stdout().flush().unwrap(); From 7749007adec3e6fe9351fe4c435d21512c6a9e96 Mon Sep 17 00:00:00 2001 From: kostDev Date: Mon, 4 Nov 2024 00:47:37 +0200 Subject: [PATCH 6/8] refactoring project --- src/main.rs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/main.rs b/src/main.rs index c0d9a3c..00c4008 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,21 +1,17 @@ use rand::{seq::{SliceRandom, IteratorRandom}, thread_rng}; use std::io::{stdout, stdin, Write}; use std::iter::repeat_with; -use genpass::consts::{ - LOW_CASE, UP_CASE, NUMBERS, SYMBOLS, ARROWS, MATH_SYMBOLS, MOOD_SYMBOLS, DEFAULT_ARGS -}; -use genpass::{ cli::handle_cli }; - +use genpass::{ consts, cli::handle_cli }; fn create_ch_pool(args: &[&str]) -> String { let mut pool = args.iter().map(|&x| match x { - "a" | "lower" => LOW_CASE, - "aa" | "upper" => UP_CASE, - "n" | "nums" => NUMBERS, - "s" | "symbols" => SYMBOLS, - "r" | "arrows" => ARROWS, - "m" | "math" => MATH_SYMBOLS, - "mm" | "mood" => MOOD_SYMBOLS, + "a" | "lower" => consts::LOW_CASE, + "aa" | "upper" => consts::UP_CASE, + "n" | "nums" => consts::NUMBERS, + "s" | "symbols" => consts::SYMBOLS, + "r" | "arrows" => consts::ARROWS, + "m" | "math" => consts::MATH_SYMBOLS, + "mm" | "mood" => consts::MOOD_SYMBOLS, custom => custom, }).collect::>(); @@ -46,7 +42,7 @@ fn main() { // first arg always number as password length let lens = tokens[0].parse::().expect("Invalid value for password length!"); let args = &tokens[1..]; - let pool = create_ch_pool(if args.is_empty() { &DEFAULT_ARGS } else { args }); + let pool = create_ch_pool(if args.is_empty() { &consts::DEFAULT_ARGS } else { args }); let password = create_password(&pool, lens); println!("Yours generated password[{lens}]: {password}"); From 58f3ab39b837cfc7b121777a13a0ebd3e12c8818 Mon Sep 17 00:00:00 2001 From: kostDev Date: Mon, 4 Nov 2024 02:34:23 +0200 Subject: [PATCH 7/8] refactoring project --- Cargo.toml | 5 +++-- src/main.rs | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4f6768f..61b2cb5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,8 +20,9 @@ path = "src/main.rs" rand = "0.8.5" [profile.release] +debug = 0 +codegen-units = 1 opt-level = "z" lto = "fat" -codegen-units = 1 panic = "abort" -debug = 0 \ No newline at end of file +strip = true \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 00c4008..5bcf7f6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@ use rand::{seq::{SliceRandom, IteratorRandom}, thread_rng}; -use std::io::{stdout, stdin, Write}; -use std::iter::repeat_with; +use std::{ + io::{ stdout, stdin, Write }, + iter::repeat_with +}; use genpass::{ consts, cli::handle_cli }; fn create_ch_pool(args: &[&str]) -> String { From a72bc7ca9ef719cf9522ee40ad34fd553110d46f Mon Sep 17 00:00:00 2001 From: kostDev Date: Wed, 6 Nov 2024 03:00:29 +0200 Subject: [PATCH 8/8] refactoring project --- src/cli.rs | 6 ++++-- src/main.rs | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index d4e86e6..0c13dc6 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,6 +1,8 @@ -use super::info::display_help; -use super::consts::CMD_HELP; use std::process::exit; +use super::{ + info::display_help, + consts::CMD_HELP, +}; pub fn handle_cli() { let _args: Vec = std::env::args().collect(); diff --git a/src/main.rs b/src/main.rs index 5bcf7f6..e3eb2ac 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use std::{ io::{ stdout, stdin, Write }, iter::repeat_with }; -use genpass::{ consts, cli::handle_cli }; +use genpass::{ consts, cli }; fn create_ch_pool(args: &[&str]) -> String { let mut pool = args.iter().map(|&x| match x { @@ -28,7 +28,7 @@ fn create_password(pool: &str, n: usize) -> String { } fn main() { - handle_cli(); + cli::handle_cli(); let mut input: String = String::new(); print!(">> ");