From 0cf3f54ee80b407ed2f9bd8e001da08d3a6192cc Mon Sep 17 00:00:00 2001 From: _ <_@_> Date: Mon, 23 Feb 2026 01:33:59 -0600 Subject: [PATCH] version 1.1.0 adds playing card and friendship bracelet passwords --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/lib.rs | 23 +++++++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a8ec120..f80a181 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,7 +42,7 @@ dependencies = [ [[package]] name = "division_of_one" -version = "1.0.2" +version = "1.1.0" dependencies = [ "rand", ] diff --git a/Cargo.toml b/Cargo.toml index 85a97a8..35b5b7f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ keywords = ["passphrase", "password"] license = "AGPL-3.0" name = "division_of_one" repository = "https://six-five-six-four.com/git/reactor/division_of_one" -version = "1.0.2" +version = "1.1.0" [dependencies] rand = { version = "0.10.0", features = ["unbiased"] } diff --git a/src/lib.rs b/src/lib.rs index f66f847..00b4845 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,15 @@ use rand::{RngExt as _, seq::IndexedRandom as _}; +const ALPHABET: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +const CARD_VALUES: &str = "A234567890JQK"; + pub fn main() -> Result<(), String> { let mut args = std::env::args(); + + // Ignore the exe name let _ = args.next(); + + // Read the first arg as a command or flag match args.next().as_deref() { None => {} Some("--version") => { @@ -16,6 +23,14 @@ pub fn main() -> Result<(), String> { println!("{}", create_pin(9)); println!("{}", create_base32(8)); + // Shuffling all 26 letters allows you to store 88 bits of information on beads on a bracelet. Destroying the bracelet doesn't reveal any information if all 26 letters are used. + println!("{}", create_shuffle(ALPHABET)); + + // Shuffling all 13 values of a suit of playing cards allow you to store 32.5 bits of information. A standard deck of cards can hold 130 bits of entropy ignoring suits. Mixing up the cards provably destroys the information. + for _ in 0..4 { + println!("{}", create_shuffle(CARD_VALUES)); + } + // Read a line of input so that the CLI can run in its own terminal without instantly closing the terminal when we exit. println!("Press Enter"); let mut input = String::new(); @@ -56,6 +71,14 @@ pub fn create_pin(len: usize) -> String { digits.join("") } +pub fn create_shuffle(input: &str) -> String { + use rand::prelude::SliceRandom; + + let mut input: Vec = input.chars().collect(); + input.shuffle(&mut rand::rng()); + String::from_iter(input.iter()) +} + pub struct Dice { words: Vec, }