はじめに
こんにちは。この記事では、Rustの勉強をかねてCLIでパスワード生成ツールを作成したので、紹介します。
github : https://github.com/tomo0106/make_password
作ったもの
CLIでランダムなパスワード生成ツールを作成しました。自分が目標にした機能は、以下の6つです。
- 乱数生成
- 桁数指定
- 数字、記号、小文字、大文字のどれを含めるか指定
- コマンドライン引数から2,3を指定
- パスワード生成個数の指定
- 生成したパスワードを保存
使用クレート
- anyhow = “1.0.40”
- clap = “3.0.0-beta.2”
- rand = “0.8.3”
ランダムパスワードの生成
これには、乱数生成にはrandクレート、エラーハンドリングにanyhowを用いました。パスワードに使う文字列とパスワードの桁数を指定して、パスワードを返却します。String型の任意の文字に参照する上手い方法がわからなかったので、結構無理やり値を持ってきてます。
/// パスワード生成
fn gen_password(password_base: &str, password_digits: i32) -> Result<String> {
if password_base.is_empty() {
bail!("There is no character string to use in the password")
}
let range = Uniform::new(0, password_base.len());
let mut rng = rand::thread_rng();
let mut password = String::new();
for _ in 0..password_digits {
let rand_index = range.sample(&mut rng);
let value = &password_base[rand_index..rand_index + 1];
// println!("{} {}",rand_index,value);
password.push_str(&value);
}
Ok(password)
}
コマンドライン引数の扱い
これには、Clapを利用しました。struct型が利用可能なbeta版を使いました。あまり使い方わかってないのですが、公式見ながらなんとか書きました。beta版なので、今後仕様が変更される可能性は高いですが、きれいに書けて良い感じです。注意点として、Option型として指定しないと引数を指定しないとエラーが吐かれます。もし、デフォルト引数的なものを指定しておき、引数があったら変更する形にする場合は、Option型にして、パターンマッチングするのが良いと思います。
use clap::Clap;
#[derive(Clap, Debug)]
#[clap(
name = "Password maker",
version = "0.0.1",
author = "Tomo",
about = "Make password"
)]
struct Opts {
/// Sets the random number of digits
#[clap(short, long)]
digits: Option<i32>,
/// Whether to include numbers.
#[clap(short, long)]
numbers: bool,
/// Whether to include lowercase letters.
#[clap(short, long)]
lowercase: bool,
/// Whether to include uppercase letters.
#[clap(short, long)]
uppercase: bool,
/// Whether to include symbols.
#[clap(short, long)]
symbol: bool,
/// Number of passwords to generate
#[clap(short, long)]
generated_number: Option<i32>,
/// Save file path(.csv)
#[clap(short, long)]
path: Option<String>,
}
完成イメージ
helpはこんな感じです。
Password maker 0.0.1
Tomo
Make password
USAGE:
main [FLAGS] [OPTIONS]
FLAGS:
-h, --help Prints help information
-l, --lowercase Whether to include lowercase letters
-n, --numbers Whether to include numbers
-s, --symbol Whether to include symbols
-u, --uppercase Whether to include uppercase letters
-V, --version Prints version information
OPTIONS:
-d, --digits <digits> Sets the random number of digits
-g, --generated-number <generated-number> Number of passwords to generate
-p, --path <path> Save file path(.csv)
使い方は、以下の通りです。パスワードの桁数と生成するパスワード数は、それぞれデフォルトで8と10に指定されています。
// -nlus => パスワードに数字、小文字、大文字、記号を含める
// -d 12 => パスワードの桁数は12
// -g 10 => 生成するパスワードは10
cargo run --bin main -- -nlus -d 12 -g 10
1 password : MvvpY7b5W^$'
2 password : ?'rJ-:%B%$%z
3 password : O9xP\k4bp/wl
4 password : bEsP~%~mpe@H
5 password : FPg'(p'H$'4k
6 password : e(aT\\csr-::
7 password : NhUmQjpb!\1i
8 password : Ql[J)]4vK+48
9 password : YK}3$n?+NPyv
10 password : Dooi_u47D8/C
おわりに
Rustの勉強としてパスワード生成CLIツールを作成しました。Clapを使うと、比較的簡単に完成度高めのCLIが作れるので、かなり良いです。まだ、Option型やResult型の使い方に慣れませんが、勉強を続けたいと思います。