| Crates.io | flowerpassword |
| lib.rs | flowerpassword |
| version | 1.0.2 |
| created_at | 2025-11-12 06:26:52.063799+00 |
| updated_at | 2025-11-12 06:26:52.063799+00 |
| description | Flower Password implementation for Rust - Deterministic password generator using HMAC-MD5 |
| homepage | https://github.com/xlsdg/flowerpassword.rust |
| repository | https://github.com/xlsdg/flowerpassword.rust |
| max_upload_size | |
| id | 1928870 |
| size | 29,962 |
Flower Password implementation for Rust - a secure password generator based on master password and key using MD5/HMAC-MD5 hashing.
This library implements the Flower Password algorithm, which generates secure, deterministic passwords based on:
The same inputs will always generate the same output, allowing you to recreate passwords without storing them.
md5 crate)Add this to your Cargo.toml:
[dependencies]
flowerpassword = "1.0"
use flowerpassword::fp_code;
fn main() {
// Generate a 16-character password for GitHub
match fp_code("my_master_password", "github.com", 16) {
Ok(password) => println!("Password: {}", password),
Err(e) => eprintln!("Error: {}", e),
}
}
use flowerpassword::fp_code;
fn main() {
let master = "my_secret_password";
// Short password (8 characters)
let short = fp_code(master, "example.com", 8).unwrap();
// Medium password (16 characters)
let medium = fp_code(master, "github.com", 16).unwrap();
// Long password (32 characters)
let long = fp_code(master, "bank.com", 32).unwrap();
println!("Short: {}", short);
println!("Medium: {}", medium);
println!("Long: {}", long);
}
use flowerpassword::{fp_code, FlowerPasswordError};
fn main() {
// Valid range is 2-32
match fp_code("password", "key", 1) {
Ok(pwd) => println!("Password: {}", pwd),
Err(FlowerPasswordError::InvalidLength(len)) => {
eprintln!("Invalid length: {}", len);
}
}
match fp_code("password", "key", 50) {
Ok(pwd) => println!("Password: {}", pwd),
Err(FlowerPasswordError::InvalidLength(len)) => {
eprintln!("Invalid length: {}", len);
}
}
}
use flowerpassword::fp_code;
fn main() {
let master = "my_master_password";
let services = vec![
"github.com",
"google.com",
"twitter.com",
"facebook.com",
];
for service in services {
let password = fp_code(master, service, 16).unwrap();
println!("{}: {}", service, password);
}
}
fp_codeGenerates a Flower Password based on master password and key.
pub fn fp_code(
password: &str,
key: &str,
length: usize
) -> Result<String, FlowerPasswordError>
Parameters:
password: Master password (any string)key: Domain or service identifier (any string)length: Output password length (2-32 characters)Returns:
Ok(String): Generated passwordErr(FlowerPasswordError): If length is invalidErrors:
FlowerPasswordError::InvalidLength: Length is not between 2 and 32The Flower Password algorithm:
Generated passwords contain:
The first character is always a letter (never a digit).
Run the test suite:
cargo test
Run tests with output:
cargo test -- --nocapture
Run doc tests:
cargo test --doc
Example outputs for reference:
| Master Password | Key | Length | Generated Password |
|---|---|---|---|
password |
key |
16 | K3A2a66Bf88b628c |
test |
github.com |
16 | D04175F7A9c7Ab4a |
mypassword |
example.com |
12 | K0CA12CecFFB |
secret |
google.com |
16 | Kc6813f75AAa6Bd1 |
This Rust implementation produces identical output to:
⚠️ Important Notes:
MIT License - see LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
# Run tests
cargo test
# Run tests with output
cargo test -- --nocapture
# Run clippy (linter)
cargo clippy -- -D warnings
# Format code
cargo fmt
# Build documentation
cargo doc --open
The project uses automated CI/CD with GitHub Actions.
Quick release:
# Using the release script (easiest)
./release.sh patch # Bug fixes: 1.0.0 → 1.0.1
./release.sh minor # New features: 1.0.0 → 1.1.0
./release.sh major # Breaking changes: 1.0.0 → 2.0.0
# Or manually with GitHub Actions
# Go to Actions → Manual Release → Run workflow
The release process automatically:
xLsDg xlsdg@qq.com (https://xlsdg.org/)