Compare commits

...

9 Commits

Author SHA1 Message Date
d8faadac13 updated README 2026-10-24 17:47:10 -04:00
ce19686ec8 updated README 2026-10-24 17:37:42 -04:00
1bb4c67818 updated README 2026-10-24 17:36:32 -04:00
2f71a281f3 v0.3.0 2026-10-24 17:09:19 -04:00
29b96985dc added nix flake 2026-10-24 17:07:47 -04:00
826cf04095 added install script 2026-10-23 21:59:43 -04:00
a0809027f5 v0.2.0 2026-10-23 13:31:03 -04:00
176c986c96 Merge pull request 'added options' (#1) from brian/options into main
Reviewed-on: #1
2026-10-23 13:10:39 -04:00
5146ecb062 added options 2026-10-23 13:09:02 -04:00
10 changed files with 420 additions and 12 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
/target /target
/result

179
Cargo.lock generated
View File

@@ -2,6 +2,56 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 4 version = 4
[[package]]
name = "anstream"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
[[package]]
name = "anstyle-parse"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.5" version = "1.0.5"
@@ -19,6 +69,52 @@ dependencies = [
"rand_core", "rand_core",
] ]
[[package]]
name = "clap"
version = "4.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa8876b300ab35ba921adea3dfd70157a46249b33f95c9084ae5709785478946"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0797fb7aeb1406c84efac526901f7ec3ead2124f946b494e72879d4b54704d"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9c751b79415d4e559e3d1fcf128e09e720eb673a06d26cf6f392d37d75b66e0"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c133bc6a41be0d194c306b5506d15e6feeea7b1d6604bd3f8310dfb2ca96486"
[[package]]
name = "colorchoice"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.3.1" version = "0.3.1"
@@ -40,12 +136,48 @@ dependencies = [
"rand_core", "rand_core",
] ]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.191" version = "0.2.191"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a"
[[package]]
name = "once_cell_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
[[package]]
name = "proc-macro2"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
dependencies = [
"proc-macro2",
]
[[package]] [[package]]
name = "r-efi" name = "r-efi"
version = "6.0.0" version = "6.0.0"
@@ -71,7 +203,52 @@ checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
[[package]] [[package]]
name = "rusty-pw" name = "rusty-pw"
version = "0.1.0" version = "0.3.0"
dependencies = [ dependencies = [
"clap",
"rand", "rand",
] ]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "3.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link",
]

View File

@@ -1,7 +1,11 @@
[package] [package]
name = "rusty-pw" name = "rusty-pw"
version = "0.1.0" version = "0.3.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
clap = { version = "4.6.7", features = ["derive"] }
rand = "0.10.3" rand = "0.10.3"
[profile.release]
strip = true

View File

@@ -1,10 +1,75 @@
# rusty-pw # rusty-pw
Rusty PW is a rust based generator for simple passwords ![](/assets/Screenshot_20261024_174545.png)
Rusty PW is a rust based generator for simple passwords. The list of words can be found at [./words.txt](./words.txt). This is a list of 200, 5 letters words that are school appropriate.
> [!WARNING]
> I do not recommend using these word-number pairs as long term security.
>
> This project was built for a niche instance where I needed to make up a lot of these types of pairs.
## Installation
### macOS Apple Silicon
1. Open a terminal and run
```bash
curl -fsSL https://git.briannelson.dev/brian/rusty-pw/raw/branch/main/install.sh | sh
```
2. Run `rusty-pw` to generate your first word-number pair
### NixOS Flakes
1. Add the flake to your inputs
```nix
rusty-pw = {
url = "git+https://git.briannelson.dev/brian/rusty-pw";
inputs.nixpkgs.follows = "nixpkgs";
};
```
2. Add the input to your configuration as an overlay
```nix
{ inputs, pkgs, ... }:
{
nixpkgs.overlays = [
inputs.rusty-pw.overlays.default
];
environment.systemPackages = with pkgs; [ rusty-pw ];
}
```
3. Rebuild your system and run `rusty-pw` to generate your first word-number pair
## Options
Here is a list of all the options available. None of these are required and a single word with 4 digits can be generated with `rusty-pw`
| Option | Description | Default | Required |
| --- | --- | --- | --- |
| `--words` | Set number of words | `1` | No |
| `--digits` | Set number of digits | `4` | No |
| `--bulk` | Generate multiple items | `1` | No |
| `--sep` | Seperator between words | "" | No |
| `--save` | Export to a save file | | No |
| `--out` | Output file name | `rusty-pw` | No |
## Usage
```bash
Random word + number generator
Usage: rusty-pw [OPTIONS]
Options:
--words <WORDS> [default: 1]
--digits <DIGITS> [default: 4]
--bulk <BULK> [default: 1]
--sep <SEP> [default: ""]
--save <SAVE> [possible values: csv, txt]
--out <OUT> [default: rusty-pw]
-h, --help Print help
-V, --version Print version
```
## Features to add ## Features to add
- [ ] option flag for multiple words or more numbers - [x] option flag for multiple words or more numbers
- `--digits 6` or `--words 2` - `--digits 6` or `--words 2`
- [ ] option flag for an array of combinations for bulk generating - [x] option flag for an array of combinations for bulk generating
- `--bulk 10` - `--bulk 10`
- [ ] option flag to export to .csv or .txt file - [x] option flag to export to .csv or .txt file
- `--save csv` - `--save csv`

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

27
flake.lock generated Normal file
View File

@@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1792773339,
"narHash": "sha256-rZLrzrC6i+jnTAlvPZHogKDulY7WWDEv9hJeHieO7Zw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "3ec636362e1816bc2f0888fa0fa2c69f1bc9e504",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

22
flake.nix Normal file
View File

@@ -0,0 +1,22 @@
{
description = "rusty-pw: random word + number generator";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
outputs = { self, nixpkgs }:
let
systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ];
forAllSystems = f:
nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system});
in
{
packages = forAllSystems (pkgs: rec {
rusty-pw = pkgs.callPackage ./package.nix { };
default = rusty-pw;
});
overlays.default = final: prev: {
rusty-pw = final.callPackage ./package.nix { };
};
};
}

43
install.sh Normal file
View File

@@ -0,0 +1,43 @@
#!/bin/sh
set -eu
HOST="https://git.briannelson.dev" # your Gitea URL, no trailing slash
REPO="brian/rusty-pw"
BIN="rusty-pw"
DIR="$HOME/.local/bin"
# Only Apple Silicon Macs are supported for now. Fail clearly otherwise.
if [ "$(uname -s)" != "Darwin" ] || [ "$(uname -m)" != "arm64" ]; then
echo "This installer only supports macOS on Apple Silicon." >&2
exit 1
fi
# Ask Gitea for the newest release tag.
tag=$(curl -fsSL "$HOST/api/v1/repos/$REPO/releases/latest" \
| sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p' | head -n 1)
if [ -z "$tag" ]; then
echo "Could not find a release for $REPO" >&2
exit 1
fi
# Download and install. curl downloads aren't quarantined, so no Gatekeeper prompt.
mkdir -p "$DIR"
echo "Downloading $BIN $tag..."
curl -fsSL "$HOST/$REPO/releases/download/$tag/$BIN-macos-arm64" -o "$DIR/$BIN"
chmod +x "$DIR/$BIN"
# Put the install folder on PATH for future terminals (zsh is the macOS default).
case ":$PATH:" in
*":$DIR:"*) ;;
*)
rc="$HOME/.zshrc"
line='export PATH="$HOME/.local/bin:$PATH"'
if ! grep -qsF "$line" "$rc"; then
echo "$line" >> "$rc"
fi
echo "Added $DIR to PATH in $rc. Open a new terminal window to use it."
;;
esac
echo "Installed $BIN $tag. Run: $BIN"

14
package.nix Normal file
View File

@@ -0,0 +1,14 @@
{ lib, rustPlatform }:
rustPlatform.buildRustPackage {
pname = "rusty-pw";
version = (lib.importTOML ./Cargo.toml).package.version;
src = lib.cleanSource ./.;
cargoLock.lockFile = ./Cargo.lock;
meta = {
description = "Random word + number generator";
mainProgram = "rusty-pw";
};
}

View File

@@ -1,16 +1,71 @@
use clap::{Parser, ValueEnum};
use rand::seq::IndexedRandom; use rand::seq::IndexedRandom;
use rand::RngExt; use rand::{Rng, RngExt};
use std::fs;
const WORDS: &str = include_str!("../words.txt"); const WORDS: &str = include_str!("../words.txt");
fn main() { #[derive(Clone, ValueEnum)]
let words: Vec<&str> = WORDS.lines().collect(); enum Format {
Csv,
Txt,
}
#[derive(Parser)]
#[command(version, about = "Random word + number generator")]
struct Args {
#[arg(long, default_value_t = 1)]
words: usize,
#[arg(long, default_value_t = 4)]
digits: usize,
#[arg(long, default_value_t = 1)]
bulk: usize,
#[arg(long, default_value = "")]
sep: String,
#[arg(long, value_enum)]
save: Option<Format>,
#[arg(long, default_value = "rusty-pw")]
out: String,
}
fn generate(words: &[&str], rng: &mut impl Rng, args: &Args) -> String {
let mut picked: Vec<&str> = Vec::with_capacity(args.words);
for _ in 0..args.words {
picked.push(words.choose(rng).expect("word list is empty"));
}
let number: String = (0..args.digits)
.map(|_| char::from(b'0' + rng.random_range(0..10u8)))
.collect();
format!("{}{}", picked.join(&args.sep), number)
}
fn main() {
let args = Args::parse();
let words: Vec<&str> = WORDS.lines().filter(|w| !w.is_empty()).collect();
let mut rng = rand::rng(); let mut rng = rand::rng();
let word = words.choose(&mut rng).expect("word list is empty"); let results: Vec<String> = (0..args.bulk)
.map(|_| generate(&words, &mut rng, &args))
.collect();
let number = rng.random_range(0..10000); for r in &results {
println!("{}", r);
}
println!("{}{:04}", word, number); if let Some(format) = &args.save {
let (ext, contents) = match format {
Format::Txt => ("txt", results.join("\n")),
Format::Csv => ("csv", format!("password\n{}", results.join("\n"))),
};
let path = format!("{}.{}", args.out, ext);
fs::write(&path, contents + "\n").expect("could not write output file");
eprintln!("saved {} results to {}", results.len(), path);
}
} }