commit ad78d15d5e27b0eedb39e61e15e775495486815b
parent 4f74bb7ec561b0406d84c54c6ef293400031dd8b
Author: Yuval Langer <yuval.langer@gmail.com>
Date: Tue, 16 Jun 2015 23:14:49 +0300
Adding a proper command line interface
Also adding methods to get the entropy of the passphrase with its own flag.
Diffstat:
M | build.rs | | | 6 | ++++++ |
M | src/diceware.rs | | | 33 | +++++++++++++++++++++++++++++++++ |
M | src/main.rs | | | 103 | +++++++++++++++++++++++++++++-------------------------------------------------- |
3 files changed, 77 insertions(+), 65 deletions(-)
diff --git a/build.rs b/build.rs
@@ -22,6 +22,8 @@ fn make_minilock_wordlist(contents: &str) -> Vec<&str> {
fn make_beale_struct(wordlist: Vec<&str>) -> std::string::String {
let mut output = std::string::String::new();
+
+ // 7776 words = 6*6*6*6*6; five 6 faced dice throws.
output.push_str("const BEALE_WORDLIST: [BealeWord; 7776] = [\n");
for word in wordlist {
output.push_str(" BealeWord(\"");
@@ -40,6 +42,8 @@ fn make_beale_struct(wordlist: Vec<&str>) -> std::string::String {
fn make_reinhold_struct(wordlist: Vec<&str>) -> std::string::String {
let mut output = std::string::String::new();
+
+ // 7776 words = 6*6*6*6*6; five 6 faced dice throws.
output.push_str("const REINHOLD_WORDLIST: [ReinholdWord; 7776] = [\n");
for word in wordlist {
output.push_str(" ReinholdWord(\"");
@@ -58,6 +62,8 @@ fn make_reinhold_struct(wordlist: Vec<&str>) -> std::string::String {
fn make_minilock_struct(wordlist: Vec<&str>) -> std::string::String {
let mut output = std::string::String::new();
+
+ // 58110 words in the MiniLock wordlist.
output.push_str("const MINILOCK_WORDLIST: [MiniLockWord; 58110] = [\n");
for word in wordlist {
output.push_str(" MiniLockWord(\"");
diff --git a/src/diceware.rs b/src/diceware.rs
@@ -14,15 +14,48 @@ pub struct ReinholdWord(&'static str);
pub struct MiniLockWord(&'static str);
impl BealeWord {
+ #[cfg(test)]
pub fn new(word: &'static str) -> BealeWord {
BealeWord(word.clone())
}
+
+ pub fn entropy() -> f64 {
+ (BEALE_WORDLIST.len() as f64).log2()
+ }
+
+ pub fn entropyn(n: u64) -> f64 {
+ BealeWord::entropy() * (n as f64)
+ }
}
impl ReinholdWord {
+ #[cfg(test)]
pub fn new(word: &'static str) -> ReinholdWord {
ReinholdWord(word.clone())
}
+
+ pub fn entropy() -> f64 {
+ (REINHOLD_WORDLIST.len() as f64).log2()
+ }
+
+ pub fn entropyn(n: u64) -> f64 {
+ ReinholdWord::entropy() * (n as f64)
+ }
+}
+
+impl MiniLockWord {
+ #[cfg(test)]
+ pub fn new(word: &'static str) -> MiniLockWord {
+ MiniLockWord(word.clone())
+ }
+
+ pub fn entropy() -> f64 {
+ (MINILOCK_WORDLIST.len() as f64).log2()
+ }
+
+ pub fn entropyn(n: u64) -> f64 {
+ MiniLockWord::entropy() * (n as f64)
+ }
}
impl rand::Rand for BealeWord {
diff --git a/src/main.rs b/src/main.rs
@@ -1,26 +1,31 @@
mod diceware;
+#[cfg(test)]
+mod tests;
+
extern crate rand;
extern crate getopts;
-//use std::env;
-//use std::io::Read;
-// use std::fs::File;
+use std::env;
-// use getopts::Options;
+use getopts::Options;
use rand::Rng;
use diceware::{BealeWord, ReinholdWord, MiniLockWord};
-/*
+
+
fn make_options() -> Options {
let mut opts = Options::new();
opts.optflag("h", "help", "this help message");
- opts.optflag("", "beale", "use the beale wordlist");
+ opts.optflag("", "minilock", "use the MiniLock wordlist (default)");
opts.optflag("", "reinhold", "use the standard wordlist");
+ opts.optflag("", "beale", "use the beale wordlist");
+ opts.optflag("e", "entropy", "display number of entropy bits");
opts.optopt("n", "nword", "number of words in a passphrase", "NWORD");
opts
}
+
fn print_passphrase(wordlist: Vec<&str>, word_num: u64) -> () {
let mut rng = rand::OsRng::new().unwrap();
let mut c = rng.choose(&wordlist);
@@ -31,16 +36,15 @@ fn print_passphrase(wordlist: Vec<&str>, word_num: u64) -> () {
println!("{}", c.unwrap());
}
+
fn print_usage(program: &str, opts: Options) {
let brief = format!("Usage: {} [options]", program);
print!("{}", opts.usage(&brief));
}
-*/
#[cfg(not(test))]
fn main() {
- /*
let args: Vec<String> = env::args().collect();
let program = args[0].clone();
@@ -54,75 +58,44 @@ fn main() {
if matches.opt_present("h") {
print_usage(&program, opts);
return;
- }
-
- let word_num: u64 = matches.opt_str("n").ok() {
- Some(n) => { n.parse::<u64>().err }
- None => {
- print_usage(&program, opts);
- return;
- }
};
- */
+
+ let word_num: u64 = matches.opt_str("n")
+ .map_or(8, |n_str| n_str.parse::<u64>().ok().unwrap());
let mut rng = rand::OsRng::new().unwrap();
- println!("Beale:");
- for _ in 1..8 {
- let word: diceware::BealeWord = rng.gen();
- print!("{} ", word);
+ if matches.opt_present("reinhold") {
+ for _ in 0..word_num {
+ let word: diceware::ReinholdWord = rng.gen();
+ print!("{} ", word);
+ }
+ println!("");
+ if matches.opt_present("entropy") {
+ println!("{}", diceware::ReinholdWord::entropyn(word_num))
+ }
+ return;
}
- println!("");
- println!("");
- println!("Reinhold:");
- for _ in 1..8 {
- let word: diceware::ReinholdWord = rng.gen();
- print!("{} ", word);
+ if matches.opt_present("beale") {
+ for _ in 0..word_num {
+ let word: diceware::BealeWord = rng.gen();
+ print!("{} ", word);
+ }
+ println!("");
+ if matches.opt_present("entropy") {
+ println!("{}", diceware::BealeWord::entropyn(word_num))
+ }
+ return;
}
- println!("");
- println!("");
- println!("MiniLock:");
- for _ in 1..8 {
+ for _ in 0..word_num {
let word: diceware::MiniLockWord = rng.gen();
print!("{} ", word);
}
println!("");
-
-}
-
-#[cfg(test)]
-mod test {
- extern crate rand;
-
- use rand::{Rng, SeedableRng, StdRng};
-
- use diceware::{ReinholdWord, BealeWord};
-
- fn make_beale_word() -> BealeWord {
- let seed: &[_] = &[1, 2, 3, 4];
- let mut rng: StdRng = SeedableRng::from_seed(seed);
- let word = rng.gen();
- word
+ if matches.opt_present("entropy") {
+ println!("{}", diceware::MiniLockWord::entropyn(word_num))
}
- fn make_reinhold_word() -> ReinholdWord {
- let seed: &[_] = &[1, 2, 3, 4];
- let mut rng: StdRng = SeedableRng::from_seed(seed);
- let word = rng.gen();
- word
- }
-
- #[test]
- fn beale_rng_test() {
- let rand_word = make_beale_word();
- assert_eq!(rand_word, BealeWord::new("ladder"))
- }
-
- #[test]
- fn reinhold_rng_test() {
- let rand_word = make_reinhold_word();
- assert_eq!(rand_word, ReinholdWord::new("ks"))
- }
}