この記事では、C#でランダムなパスワードを生成するサンプルコードを紹介します。
スポンサーリンク
数値のみのランダムなパスワード
Random
クラスを使って、数値のみのランダムなパスワードを生成します。
Linqを使えば、次のような感じでシンプルに書けます。
Random rng = new Random();
string password = string.Join("",
Enumerable.Range(0, 10).Select(n => rng.Next(0, 9).ToString())
);
Console.WriteLine(password); //-> 7821867520s
記号・英字・数字を1つ以上含むパスワードを生成
パスワードの要件によっては、複数の文字種をそれぞれ最低でも1つ以上含める必要があるケースもあります。
次のサンプルコードは、少なくとも数字、大文字、小文字および記号を1文字以上含むランダムなパスワードを生成する例です。コピペして使えるようにクラス形式のサンプルコードにしています。
using System;
using System.Linq;
static class RandomPassword
{
private const string ASCII_NUMBER = "0123456789"; //数字
private const string ASCII_UPPER_ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //英字大文字
private const string ASCII_LOWER_ALPHA = "abcdefghijklmnopqrstuvwxyz"; //英字小文字
private const string ASCII_MARK = "!\"#$%&'()*+-/<=>?@;[]^"; //記号
private static readonly Random rng = new Random(); //ランダムクラス
/// <summary>
/// ランダムな文字列を生成する。
/// </summary>
/// <param name="length">文字列の長さ</param>
/// <returns>数字、大文字、小文字および記号を1文字以上含むランダムな文字列</returns>
public static string Generate(int length)
{
string allSource = ASCII_NUMBER + ASCII_UPPER_ALPHA + ASCII_LOWER_ALPHA + ASCII_MARK;
//各文字種を最低1文字含める
string password = Choice(ASCII_NUMBER)
+ Choice(ASCII_UPPER_ALPHA)
+ Choice(ASCII_LOWER_ALPHA)
+ Choice(ASCII_MARK);
//任意の文字種でランダムな文字を生成
int cnt = length - password.Length;
for (int i = 0; i < cnt; i++)
{
password += Choice(allSource);
}
//生成した文字列をシャッフルして返す
return string.Join("", password.OrderBy(n => rng.Next()));
}
/// <summary>
/// 指定された文字列ソースからランダムに1文字選択する
/// </summary>
/// <param name="source">文字列ソース</param>
/// <returns>ランダムに選択した文字</returns>
private static string Choice(string source)
{
return source[rng.Next(0, source.Length - 1)].ToString();
}
}
■ 実行結果
上のサンプルコードを、RandomPassword.Generate(10)
のようにして呼び出すと、10文字のランダムなパスワードを生成します。
apM3>Mvo5u
Randomクラスはスレッドセーフではない
ランダムなパスワードや乱数の生成などに用いられるRandom
クラスですが、このクラスはスレッドセーフではありません。
また、スレッドセーフではないからと言って、乱数を生成する度にRandom
クラスのインスタンスを作成すると、同一の数値シーケンスを生成する乱数ジェネレーターが作成され、結果的に同じパスワードが生成される恐れがあります。
Webアプリなどのマルチスレッド環境では、C#だったらLock
、Visual BasicならSyncLock
ステートメントを使って、複数のスレッドがRandom
クラスのインスタンスにアクセスできないように制御します。
0 件のコメント:
コメントを投稿