Compare commits
9 Commits
13f9d42c78
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| d8faadac13 | |||
| ce19686ec8 | |||
| 1bb4c67818 | |||
| 2f71a281f3 | |||
| 29b96985dc | |||
| 826cf04095 | |||
| a0809027f5 | |||
| 176c986c96 | |||
| 5146ecb062 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
/target
|
||||
/result
|
||||
179
Cargo.lock
generated
179
Cargo.lock
generated
@@ -2,6 +2,56 @@
|
||||
# It is not intended for manual editing.
|
||||
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]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.5"
|
||||
@@ -19,6 +69,52 @@ dependencies = [
|
||||
"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]]
|
||||
name = "cpufeatures"
|
||||
version = "0.3.1"
|
||||
@@ -40,12 +136,48 @@ dependencies = [
|
||||
"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]]
|
||||
name = "libc"
|
||||
version = "0.2.191"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "r-efi"
|
||||
version = "6.0.0"
|
||||
@@ -71,7 +203,52 @@ checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
|
||||
|
||||
[[package]]
|
||||
name = "rusty-pw"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"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",
|
||||
]
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
[package]
|
||||
name = "rusty-pw"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.6.7", features = ["derive"] }
|
||||
rand = "0.10.3"
|
||||
|
||||
[profile.release]
|
||||
strip = true
|
||||
73
README.md
73
README.md
@@ -1,10 +1,75 @@
|
||||
# rusty-pw
|
||||
Rusty PW is a rust based generator for simple passwords
|
||||

|
||||
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
|
||||
- [ ] option flag for multiple words or more numbers
|
||||
- [x] option flag for multiple words or more numbers
|
||||
- `--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`
|
||||
- [ ] option flag to export to .csv or .txt file
|
||||
- [x] option flag to export to .csv or .txt file
|
||||
- `--save csv`
|
||||
|
||||
BIN
assets/Screenshot_20261024_174545.png
Normal file
BIN
assets/Screenshot_20261024_174545.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
27
flake.lock
generated
Normal file
27
flake.lock
generated
Normal 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
22
flake.nix
Normal 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
43
install.sh
Normal 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
14
package.nix
Normal 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";
|
||||
};
|
||||
}
|
||||
69
src/main.rs
69
src/main.rs
@@ -1,16 +1,71 @@
|
||||
use clap::{Parser, ValueEnum};
|
||||
use rand::seq::IndexedRandom;
|
||||
use rand::RngExt;
|
||||
use rand::{Rng, RngExt};
|
||||
use std::fs;
|
||||
|
||||
const WORDS: &str = include_str!("../words.txt");
|
||||
|
||||
fn main() {
|
||||
let words: Vec<&str> = WORDS.lines().collect();
|
||||
#[derive(Clone, ValueEnum)]
|
||||
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 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);
|
||||
|
||||
println!("{}{:04}", word, number);
|
||||
for r in &results {
|
||||
println!("{}", r);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user