パスワード用乱数の生成 英数字記号全部混ぜるお^^

パスワードは登録するサイトごとに変えるのが基本ですが、いちいち自分で考えてたらそんな何種類も思いつかんし、主観が介在してしまい、セキュリティ上望ましくないσ(^_^;)アセアセ...

ここはド初心者がひとつ勉強がてらphpで乱数つくってみる。

要件
・或るサイトにログインする際のパスワードを作る
・今回使える文字は0-9,a-z,それから一部の記号なので、これを全部混ぜたい。
・最大8文字なので一番強力な8文字のパスワードにするが、他でも流用できるように文字数を引数にしてはき出すようにしたい。

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

<?
function createPassword($length = 8){
 
    $pwd_strings = array("sletter" => range('a', 'z'),
	                         "number"  => range('0', '9'),
	                         "symbol"  =>array(",", ".", ";", ":", "!", "?", "#", "@", "$", "%", "^", "&", "*", "(", ")", "{", "}", "[", "]", "_", "=", "+", "/", "\\", "-")
				);
    $pwd = array();
    while (count($pwd) < $length) {
        if (count($pwd) < 3) {
            $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 var_dump(implode($pwd));
}
echo createPassword() ;
?>

さて、動きはしたものの、アホなのでなんでそうなるのか、なかなか理解できませんでした。σ(^_^;)アセアセ...
ド初心者なので、ここはしつこいほどコメントつけて復習σ(^_^;)アセアセ... そして写経。

<?php
// 引数はパスワードの文字数 デフォルトで8文字にしとく。
function createPassword($length = 8){

//二次元配列。一次配列のキーを文字の種類で分ける。
//range(ASCII文字,ASCII文字)で、ASCII文字の順番で最初と最後の範囲を指定し、配列にしてぶっ込む。

//e.g. $pwd_strings['sletter'][0]に'a'が,['sletter'][1]に'b'が、['symbol'][0]に','が入る。
 
    $pwd_strings = array("sletter" => range('a', 'z'),
	                         "number"  => range('0', '9'),
	                         "symbol"  =>array(",", ".", ";", ":", "!", "?", "#", "@", "$", "%", "^", "&", "*", "(", ")", "{", "}", "[", "]", "_", "=", "+", "/", "\\", "-")

				);
// 配列$pwd。 後で$pwd[] = *** として繰り返し処理させて、要素を追加していく。$pwd[] = とすれば キーには自動で数字が割り振られる。
// $pwd[0]から$pwd[7]まで一文字ずつ文字を入れる。

    $pwd = array();
 
// 数字、文字、記号の3種類必ず入れるための処理
//count(array)で配列の要素数を調べる
//key(array)で配列$pwd_stringsにおいて、 内部ポインタが現在指している要素のキーを返す。最初は'sletter' 。
//next(array)で配列のポインタを一つ先に進める。 現在'sletter'だったら、'number'になる。

    while (count($pwd) < $length) {
        if (count($pwd) < 3) { 
            $key = key($pwd_strings);
            next($pwd_strings);
        } else {

//3種類突っ込んだら、 後はランダムに取得。
//array_rand(array)は配列のキーをランダムで返す。
//$pwd[0]にa-z、$pwd[1]に0-9,$pwd[2]に記号をいれて、$pwd[3]からは何でもいい。

            $key = array_rand($pwd_strings);
        }

        $pwd[] = $pwd_strings[$key][array_rand($pwd_strings[$key])];
    }

//e.g. array_rand($pwd_strings['sletter']) で0-25のどれかが返る。
//$pwd_strings[0][0-25のどれか] で a-zのどれかが返り、 $pwd[0]に代入される。
//$pwd[0]が代入されたので、count($pwd) == 1 になる。

//array_rand($pwd_strings['number']) で0-8のどれかが返る。
//$pwd_strings[1][0-8のどれか]で0-9のどれかが返り、$pwd[1]に代入される。
//$pwd[1]が代入されたので、$pwd[0]、$pwd[1] が埋められ、count($pwd) == 2 になる。

//array_rand($pwd_strings['symbol']) で0-24のどれかが返る。(今回の記号は25種類)
//$pwd_strings[2][0-25のどれか]で記号のどれかが返り、$pwd[2]に代入される。
//$pwd[2]が代入されたので、$pwd[0]、$pwd[1] 、$pwd[2]が埋められ、count($pwd) == 3 になる。

//array_rand($pwd_strings['sletter','number','symbol'のどれか])で 0-25、0-8,0-24のどれかが返る。
//$pwd_strings[なんか][なんか]で或る文字が返り、$pwd[3]に代入される。
//$pwd[3]が代入されたので、$pwd[0]、$pwd[1] 、$pwd[2],$pwd[3]が埋められ、count($pwd) == 4 になる。

//$pwd[7]まで埋められる。

 
// 生成したパスワードの順番をランダムに並び替え
//shuffle(array)で,配列の要素をシャッフルする。
    shuffle($pwd);
//implode(array)で、配列の要素を連結する。 
//長さやstring型であるのがわかるようにvar_dump

    return var_dump(implode($pwd));
}

echo "<p><strong>0-9,a-zと , . ; : ! ? # @ $ % ^ & * ( ) { } [ ] _ = + / \ -から成り、必ず3種類全て使用した、パスワード</strong><br>";
echo createPassword() . "</p>";

//結果例:string(8) "u31oh%b."

?>

以前にa-zと0-9から成る乱数をつくったときはこう書きましたが、これだと文字だけ、数字だけになる可能性があります。

<?
function makeRandStr($length) {
	$str = array_merge(range('a', 'z'), range('0', '9'));
	$r_str = null;
	for ($i = 0; $i < $length; $i++) {

// count($str)で array $strの要素数を返す。キーにして使いたいので、-1
//rand ( int , int)で端点を含む数字を一つ返す。
//$r_strに連結代入していく。
		$r_str .= $str[rand(0, count($str)-1)];
	}

echo $length . "文字のa-zと0-9から成るパスワード<br>";
	var_dump($r_str);
}

makeRandStr(20);

?>