Skip to content

Commit

Permalink
fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
rtaycher committed Mar 4, 2016
1 parent aede1ef commit 365e747
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 22 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
target
Cargo.lock
7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
[package]
name = "make_password"
version = "0.1.0"
version = "0.2.0"
authors = ["Roman A. Taycher <[email protected]>"]

[dependencies]
rand = "0.3"
rand = "0.3"
rustc-serialize = "0.3"
clap = "2.1"
itertools = "0.4"
52 changes: 39 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -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.
98 changes: 91 additions & 7 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -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<String>,
}

fn main() {
let words: Vec<&str> = WORDS_FILE.lines().collect();

let m = App::new("make_password")
.version(crate_version!())
.author("Roman A. Taycher <[email protected]>")
.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 <[email protected]>")
.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::<Vec<_>>().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::<usize>() % 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::<usize>() % 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::<usize>() % 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);
}

0 comments on commit 365e747

Please sign in to comment.