From 365e7474b53735adae712726baa0ca0341d054f1 Mon Sep 17 00:00:00 2001 From: "Roman A. Taycher" Date: Fri, 4 Mar 2016 11:43:37 -0800 Subject: [PATCH] fixed --- .gitignore | 1 + Cargo.toml | 7 ++-- README.md | 52 +++++++++++++++++++++------- src/main.rs | 98 +++++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 136 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index eb5a316..a9d37c5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml index 5b073fa..f8aec83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,10 @@ [package] name = "make_password" -version = "0.1.0" +version = "0.2.0" authors = ["Roman A. Taycher "] [dependencies] -rand = "0.3" \ No newline at end of file +rand = "0.3" +rustc-serialize = "0.3" +clap = "2.1" +itertools = "0.4" \ No newline at end of file diff --git a/README.md b/README.md index 955fe08..57e9449 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,39 @@ -# make_password - -generate xkcd horse battery correct staple style passwords - -![Password Style](http://imgs.xkcd.com/comics/password_strength.png "To anyone who understands information theory and security and is in an infuriating argument with someone who does not (possibly involving mixed case), I sincerely apologize.") - -Most of the time I'm satisfied with the random -passwords generated and saved in keepass, but sometimes -I need passwords I can manually re-enter easily if not -necessarily remember. - - -I'll add some basic customization flags soon. +# make_password + +generate memorable and/or easily transcribable passwords including + +1. xkcd horse battery correct staple style passwords +2. Interspersed passwords + +![Password Style](http://imgs.xkcd.com/comics/password_strength.png "To anyone who understands information theory and security and is in an infuriating argument with someone who does not (possibly involving mixed case), I sincerely apologize.") + +Most of the time I'm satisfied with the random +passwords generated and saved in keepass, but sometimes +I need passwords I can manually re-enter easily if not +necessarily remember. + +run `make_password -n x` to change the # of words used (default to 5) + +run `make_password -a` to add a random a random char followed by a random symbol as an extra word in a random position + +ex: + +`make_password -n 3 -a` + +might return: + +`triumph syndicating 6@ sacrificial` + +alternatively you can use this to mix 2 phrases for an easily memorable password. + +Of course it doesn't come up with the phrases but it saves from having to write out the results yourself. + +Especially usefull for re-generating the actual password for cmdline entry(where you can't move left and right). + +Running + + make_password mixed 'a bee CD' 'Dog Party? 2017!' + +results in `aDobgeePaCrDty?2017!` + +If anyone has any other usefull password generation patterns I'd be willing to add them. \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 1731741..cebe22d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,102 @@ extern crate rand; +extern crate rustc_serialize; + +#[macro_use] +extern crate clap; + +extern crate itertools; + use rand::{thread_rng, Rng}; +use clap::{App, Arg, SubCommand}; +use itertools::Itertools; + static WORDS_FILE: &'static str = include_str!("american-english-small"); + +#[derive(Debug, RustcDecodable)] +struct Args { + num_of_password_words: isize, + add_random_sym_and_char: bool, + mixed: bool, + arg_interspersed_phrases: Vec, +} + fn main() { - let words: Vec<&str> = WORDS_FILE.lines().collect(); + + let m = App::new("make_password") + .version(crate_version!()) + .author("Roman A. Taycher ") + .about("generate easy to remember passwords(not garunteed to be safe use at your \ + own risk)") + .arg(Arg::with_name("num_of_password_words") + .short("n") + .takes_value(false) + .default_value("5") + .help("Number of words in the password")) + .arg(Arg::with_name("add_random_sym_and_char") + .short("a") + .takes_value(false) + .help("add a random symbol and char followed by a random char")) + .subcommand(SubCommand::with_name("mixed") + .about("alternate password scheme mixing 2 phrases") + .version(crate_version!()) + .author("Roman A. Taycher ") + .arg(Arg::with_name("p1") + .help("phrase 1") + .required(true) + .index(1)) + .arg(Arg::with_name("p2") + .help("phrase 2") + .required(true) + .index(2))) + .get_matches(); + let thing; + if let Some(sub_command) = m.subcommand_matches("mixed") { + let mut password = String::new(); + let p1 = sub_command.value_of("p1").unwrap(); + let p2 = sub_command.value_of("p2").unwrap(); + + for ze in p1.chars().interleave(p2.chars()) { + password.push(ze); + // match ze { + // Both(ch1, ch2) => { + // password.push(ch1); + // password.push(ch2); + // } + // Left(ch1) => { + // password.push(ch1); + // } + // Right(ch1) => { + // password.push(ch1); + // } + // } + } + let password = password.split_whitespace().collect::>().concat(); + println!("password:\n\t{:}", password); + return; + } + + let words: Vec<&str> = WORDS_FILE.lines() + .filter(|w| !w.ends_with("'s"))// ignore possessives + .collect(); let len = words.len(); let mut rng = thread_rng(); - let password_words: Vec<&str> = (1..5).map(|_| words[rng.gen::() % len]).collect(); - // let numbers = "0123456789"; - // let symbols = "!@#$%^&*()-+"; + let mut password_words: Vec<&str> = (0..(value_t!(m, "num_of_password_words", u32) + .unwrap_or(5))) + .map(|_| words[(rng.gen::() % len) - 1]) + .collect(); + let numbers = "0123456789".as_bytes(); + let symbols = "!@#$%^&*()-+".as_bytes(); + + thing = format!("{:}{:}", + *rng.choose(&numbers).unwrap() as char, + *rng.choose(&symbols).unwrap() as char); - + if m.is_present("add_random_sym_and_char") { + let thing_index = rng.gen::() % password_words.len(); + password_words.insert(thing_index, &thing); + } let password = password_words.join(" "); - println!("{:}", password); - // println!("# of words {:}", len); + println!("password:\n\t{:}", password); }