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:
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))
+ }
+}