rusty-diceware

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit d1a1ef0fa2d708d71cdc01ab6d339b4930709ac5
parent 828f85f2a27a85826cfa327404823609c5a8c1d0
Author: Yuval Langer <yuvallangerontheroad@gmail.com>
Date:   Mon,  5 Sep 2022 18:48:12 +0300

Deduplicate printing code.

* Deduplicate word printing code by using the trait `Word` and moving that code into a a generic function which uses that trait.
* Add a commented out wordlist command line option for a future backwards compatibility breaking version.
* Remove some commented out code.
* Use the `Self` keyword in `impl`s instead of the type's concrete name.
* Add a CHANGELOG.

Diffstat:
ACHANGELOG.md | 10++++++++++
MCargo.toml | 2+-
MREADME.md | 2++
Msrc/bin/diceware.rs | 59+++++++++++++++++++++--------------------------------------
Msrc/lib.rs | 99+++++++++++++++++++++++++++++++++++++++++++------------------------------------
5 files changed, 88 insertions(+), 84 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -0,0 +1,10 @@ +## v0.3.4 + +* Deduplicate word printing code by using the trait `Word` and moving + that code into a a generic function which uses that trait. +* Add a commented out wordlist command line option for a future + version. +* Remove some commented out code. +* Use the `Self` keyword in `impl`s instead of the type's concrete + name. +* Add this CHANGELOG. diff --git a/Cargo.toml b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "diceware" -version = "0.3.3" +version = "0.3.4" authors = ["Yuval Langer <yuvallangerontheroad@gmail.com>"] license = "AGPL-3.0" repository = "https://gitlab.com/yuvallanger/rusty-diceware" diff --git a/README.md b/README.md @@ -5,6 +5,8 @@ sans dice, written in [rustlang][rustlang]. Please use [Gitlab][gitlab-mirror] for anything whatsoever. Github is just a mirror. +[CHANGELOG](/CHANGELOG.md) here. + Inspired by the great passphrase generating solution [Diceware][diceware] ([Wayback Machine mirror][diceware-wayback]) invented by [Arnold G. Reinhold][arnold] ([Wayback Machine mirror][arnold-wayback]) and by Randall diff --git a/src/bin/diceware.rs b/src/bin/diceware.rs @@ -1,15 +1,10 @@ extern crate getopts; extern crate rand; -//use std::env; - use getopts::Options; use rand::thread_rng; -use rand::Rng; use std::process::exit; -//use diceware::{BealeWord, ReinholdWord, MiniLockWord}; - fn make_options() -> Options { let mut opts = Options::new(); opts.optflag("h", "help", "this help message"); @@ -24,6 +19,7 @@ fn make_options() -> Options { "the delimiter character used to separate the words", "DELIM", ); + //opts.optopt("l", "wordlist", "Wordlist to use (minilock (default), reinhold, or beale)", "WORDLIST"); opts } @@ -60,49 +56,36 @@ fn main() { .opt_str("d") .map_or(' ', |n_str| n_str.parse::<char>().ok().unwrap()); + let is_entropy_printed = matches.opt_present("entropy"); + let mut rng = thread_rng(); if word_num != 0 { if matches.opt_present("reinhold") { - for _ in 0..(word_num - 1) { - let word: diceware::ReinholdWord = rng.gen(); - print!("{}{}", &word, delimiter); - } - let word: diceware::ReinholdWord = rng.gen(); - print!("{}", word); - - println!(); - if matches.opt_present("entropy") { - println!("{}", diceware::ReinholdWord::entropyn(word_num)) - } + diceware::print_words::<diceware::ReinholdWord>( + &word_num, + &delimiter, + &is_entropy_printed, + &mut rng, + ); return; } if matches.opt_present("beale") { - for _ in 0..(word_num - 1) { - let word: diceware::BealeWord = rng.gen(); - print!("{}{}", &word, delimiter); - } - let word: diceware::BealeWord = rng.gen(); - print!("{}", word); - - println!(); - if matches.opt_present("entropy") { - println!("{}", diceware::BealeWord::entropyn(word_num)) - } + diceware::print_words::<diceware::BealeWord>( + &word_num, + &delimiter, + &is_entropy_printed, + &mut rng, + ); return; } - for _ in 0..(word_num - 1) { - let word: diceware::MiniLockWord = rng.gen(); - print!("{}{}", &word, delimiter); - } - let word: diceware::MiniLockWord = rng.gen(); - print!("{}", word); - - println!(); - if matches.opt_present("entropy") { - println!("{}", diceware::MiniLockWord::entropyn(word_num)) - } + diceware::print_words::<diceware::MiniLockWord>( + &word_num, + &delimiter, + &is_entropy_printed, + &mut rng, + ); } } diff --git a/src/lib.rs b/src/lib.rs @@ -1,6 +1,8 @@ extern crate rand; +use rand::rngs::ThreadRng; use rand::seq::SliceRandom; +use rand::Rng; use std::fmt; include!(concat!(env!("OUT_DIR"), "/diceware.rs")); @@ -14,45 +16,55 @@ pub struct ReinholdWord(&'static str); #[derive(Debug, Clone, Eq, PartialEq, Copy)] pub struct MiniLockWord(&'static str); -impl BealeWord { - pub fn new(word: &'static str) -> BealeWord { - BealeWord(word) +pub trait Word { + fn new(word: &'static str) -> Self; + + fn entropy() -> f64; + + fn entropyn(n: u64) -> f64 { + Self::entropy() * (n as f64) + } +} + +impl Word for BealeWord { + fn new(word: &'static str) -> Self { + Self(word) } - pub fn entropy() -> f64 { + fn entropy() -> f64 { (BEALE_WORDLIST.len() as f64).log2() } - pub fn entropyn(n: u64) -> f64 { - BealeWord::entropy() * (n as f64) + fn entropyn(n: u64) -> f64 { + Self::entropy() * (n as f64) } } -impl ReinholdWord { - pub fn new(word: &'static str) -> ReinholdWord { - ReinholdWord(word) +impl Word for ReinholdWord { + fn new(word: &'static str) -> Self { + Self(word) } - pub fn entropy() -> f64 { + fn entropy() -> f64 { (REINHOLD_WORDLIST.len() as f64).log2() } - pub fn entropyn(n: u64) -> f64 { - ReinholdWord::entropy() * (n as f64) + fn entropyn(n: u64) -> f64 { + Self::entropy() * (n as f64) } } -impl MiniLockWord { - pub fn new(word: &'static str) -> MiniLockWord { - MiniLockWord(word) +impl Word for MiniLockWord { + fn new(word: &'static str) -> Self { + Self(word) } - pub fn entropy() -> f64 { + fn entropy() -> f64 { (MINILOCK_WORDLIST.len() as f64).log2() } - pub fn entropyn(n: u64) -> f64 { - MiniLockWord::entropy() * (n as f64) + fn entropyn(n: u64) -> f64 { + Self::entropy() * (n as f64) } } @@ -62,17 +74,9 @@ impl rand::distributions::Distribution<BealeWord> for rand::distributions::Stand } } -/* -impl rand::Rand for BealeWord { - fn rand<R: rand::Rng>(rng: &mut R) -> BealeWord { - rng.choose(&BEALE_WORDLIST).unwrap().clone() - } -} -*/ - impl fmt::Display for BealeWord { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let BealeWord(w) = self; + let Self(w) = self; write!(f, "{}", w) } } @@ -83,17 +87,9 @@ impl rand::distributions::Distribution<ReinholdWord> for rand::distributions::St } } -/* -impl rand::Rand for ReinholdWord { - fn rand<R: rand::Rng>(rng: &mut R) -> ReinholdWord { - rng.choose(&REINHOLD_WORDLIST).unwrap().clone() - } -} -*/ - impl fmt::Display for ReinholdWord { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let ReinholdWord(w) = self; + let Self(w) = self; write!(f, "{}", w) } } @@ -104,17 +100,30 @@ impl rand::distributions::Distribution<MiniLockWord> for rand::distributions::St } } -/* -impl rand::Rand for MiniLockWord { - fn rand<R: rand::Rng>(rng: &mut R) -> MiniLockWord { - rng.choose(&MINILOCK_WORDLIST).unwrap().clone() - } -} -*/ - impl fmt::Display for MiniLockWord { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let MiniLockWord(w) = self; + let Self(w) = self; write!(f, "{}", w) } } + +pub fn print_words<T: Word + std::fmt::Display>( + word_num: &u64, + delimiter: &char, + is_entropy_printed: &bool, + rng: &mut ThreadRng, +) where + rand::distributions::Standard: rand::distributions::Distribution<T>, +{ + for _ in 0..(word_num - 1) { + let word: T = rng.gen(); + print!("{}{}", &word, delimiter); + } + let word: T = rng.gen(); + print!("{}", word); + + println!(); + if *is_entropy_printed { + println!("{}", T::entropyn(*word_num)) + } +}