[PHP] ポリシーにあわせてランダムなパスワードを生成する | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

ユーザーに割り振る初期のパスワードを生成する際には、ある程度ランダムなものを渡す必要があったりします。
例えば、このランダムなパスワードを単純に作るのであれば


<?php

function createPassword($length = 8) {

// ASCIIコード表の!から~までの英数字・記号を配列に格納
    $letter = range('!', '~');

// ランダムにパスワードの文字数分だけキーを取得
    $pwd_key = array_rand($letter, $length);
    $pwd = array();

    foreach ($pwd_key as $key => $value) {
        $pwd[] = $letter[$value];
    }

// 出来上がったパスワードの配列を結合して文字列に
    return implode($pwd);
}

echo createPassword();

?>


のように作ってもよいのですが、これだと運が悪ければ(良ければ?)、英字だけとか、数字だけのパスワードが出来上がってしまいます。

簡単に解説すると、range 関数により、記号と英数字を一つの配列に入れて、そこからarray_rand 関数で任意の文字列を取ってパスワードを作り出しています。

array_rand関数でランダムに文字をとっていますので、英字だけの場合や数字だけのパスワードが作られる可能性もあります。(確率的には低いですけど)


もう少し複雑なものをつ作るためには一工夫が必要です。

下記のサンプルでは、英小文字、英大文字、数字、記号を最低1つずつ含むパスワードを生成しています。

<?php
function createPassword($length = 8){

    $pwd_strings = array("sletter" => range('a', 'z'),
                         "cletter" => range('A', 'Z'),
                         "number"  => range('0', '9'),
                         "symbol"  => array_merge(range('!', '/'), range(':', '?'), range('{', '~')));

    $pwd = array();

    while (count($pwd) < $length) {

// 4種類必ず入れる
        if (count($pwd) < 4) {
            $key = key($pwd_strings);
            next($pwd_strings);
        } else {
// 後はランダムに取得
            $key = array_rand($pwd_strings);
        }
        $pwd[] = $pwd_strings[$key][array_rand($pwd_strings[$key])];
    }

// 生成したパスワードの順番をランダムに並び替え
    shuffle($pwd);

    return implode($pwd);
}

echo createPassword() . "\n";

?>



業務上の理由からこういう複雑なポリシーの元でシステムを利用いけない場合もありますからね。

whileのループ内をうまく改変するともっと違ったポリシーのパスワードを生成できます。

(記号は除きたいとか、数字は必ず2つ以上入れたいとか)


後は、記号や数字を含んだパスワードの場合、見分けがつきにくい文字列もあったりしますので、ユーザーが見間違うことを考慮して、そういった紛らわしい文字列は、初期のパスワードには含めないというような考えも必要になるかもしれません。(数字の0と、英小文字のoと、英大文字のOは見間違いやすいから含めないようにするとか)

パスワードはどんなシステムでもつき物になることが多いので、こういう関数を一つ作っておいたら幸せになるかもしれません。