
サンプル・プログラムのダウンロード
password.php | サンプル・プログラム本体。 |
バージョン | 更新日 | 内容 |
---|---|---|
1.1.0 | 2023/01/06 | 関数名などを読みやすいものに改訂 |
1.0.0 | 2004/09/26 | 初版 |
解凍できたら、password.php というファイル名で Apacheの仮想ディレクトリが通っているディレクトリにセーブする。
なお、これ以降の画面に表示している行番号は説明の便宜上のものであり、ソースプログラムには含んでいない。
   1: <?php
   2: /** password.php
   3: * パスワードを生成するPHPプログラム
   4: *
   5: * @copyright (c)studio pahoo
   6: * @author パパぱふぅ
   7: * @動作環境 PHP 4/5/7/8
   8: * @参考URL https://www.pahoo.org/e-soul/webtech/php01/php04-01.shtm
   9: */
  10: /**
  11: * マイクロ秒を使って乱数器に種まきする。
  12: */
  13: function sowSeeds() {
  14: list($usec, $sec) = explode(' ', microtime());
  15: mt_srand((float)$sec + ((float)$usec * 100000));
  16: }
  17:
  18: /**
  19: * パスワードを生成する。
  20: * @param int $length 生成するパスワードの長さ
  21: * @param string $characters パスワードに使う文字の並び(半角文字)
  22: * @return string パスワード
  23: */
  24: function getPassword($length, $characters) {
  25: $num = strlen($characters) - 1;
  26:
  27: //$charactersからランダムに1文字ずつ選んで$passwordに結合していく
  28: $password = '';
  29: for ($i = 0; $i < $length; $i++) {
  30: $position = (int)mt_rand(0, $num);
  31: $password = $password . substr($characters, $position, 1); //1文字追加
  32: }
  33: return $password;
  34: }
  35:
  36: //メインプログラム ========================================================
  37: //長さ10文字、英大文字・数字混在のパスワードを生成、表示する
  38: print getPassword(10, '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ');
  39:
  40: /*
  41: ** バージョンアップ履歴 ===================================================
  42: *
  43: * @version 1.1.0 2023/01/06 関数名などを読みやすいものに改訂
  44: * @version 1.0.0 2004/09/26 初版
  45: */
  46: ?>
サンプル・プログラムの実行方法
これがPHPプログラムである。
PHPプログラムの始まりと終わり
コメント
PHPはC, C++と同様のコメント記法を採用している。
すなわち、
- // から行末まではコメント(1行コメント)
- /* ... */ の間はコメント(複数行コメント)
ユーザー定義関数

ユーザー定義関数は、

のように記述する。password.php の sowSeeds や getPassword がユーザー定義関数である。

関数名は、アンダーバーまたはアルファベットで始まる文字列で、2文字目以降は数字も混在してよい。英小文字・大文字は区別される。
引き数には、この関数内だけに通用する(スコープ)変数を指定する。
PHPの変数は必ず $ で始まる。次に、アンダーバーまたはアルファベットが続き、その次からは数字も混在してよい。英小文字・大文字は区別される。
引き数を指定しない場合は、Cのようなvoid指定は不要。

PHPでは変数の「型」を意識する必要がなく、関数や引数に型を明示する必要はない。ただ、浮動小数演算しようとしたつもりが整数演算として解釈され、計算結果が間違う可能性がある。そこで、次のように float と追記することで、変数が浮動小数であることをPHP処理系に指示した。
  15: mt_srand((float)$sec + ((float)$usec * 100000));
  16: }
組み込み関数
画面表示やDBアクセスに始まって、数字に3桁区切りのカンマを付けたり、文字列からHTMLの外したりと、考えられるルーチンワークのほとんどは組み込み関数で用意されている。この点がPHPの大きな魅力である。
他方、これら組み込み関数はPHPのバージョンによって変化しており、参考書籍の情報は古いことが多い。そこで、最新のオンライン・マニュアル(日本語)を参考にした方がよい。

password.php では、まず、12行目の関数 microtime が組み込み関数である。
これは、文字列 "msec sec" を返す。sec は現在時刻を Unix epoch (1970年1月1日 00:00:00)からの通算秒としたもので、msec は マイクロ秒の部分である。

関数 explode は、指定した文字で文字列を分解し、各々を配列に入れて戻す組み込み関数だ。12行目では空白を区切り文字にして分解している。

関数 list はPHPならではのユニークな組み込み関数で、関数 explode のように戻り値が配列である場合、一気に複数の独立した変数に代入することができる。ここでは、変数 $usec にミリ秒が、変数 $sec に秒が代入される。
関数 mt-srand は乱数の種(シード)を設定する関数である。乱数の乱れを向上させるため、後述の関数 mt-rand を使う前に必ず呼び出すのが定石である。
演算子
文字列を結合する演算子は . (ピリオド)である。

PHPはデータ型の概念を持たないので、演算子によって結果が異なることがある。
たとえば、$a = 1, $b = 2のとき、$a + $b の結果は2であるが、 $a . $b の結果は11となる。数値として加算が行われたか、文字列として接続が行われたかの違いである。
そこで、計算結果を明らかにするために、明示的に型を指定することがある。これが「型指定演算子」で、int(整数)、float(単精度浮動小数)、double(倍精度浮動小数)、string(文字列)、array(配列)、object(オブジェクト)がある。

その他にも様々な演算子がある。

演算子や関数を用いた「式」はPHPプログラムの最小構成単位である。詳細はオンラインマニュアルを参照のこと。
文字列操作
実際に、この関数を呼び出すのは34行目で、10桁、英数大文字から成るパスワードを生成させている。

23行目の関数 strlen は、引き数に与えられた文字列の長さを返す。ここでは、パスワードに使用する文字種の数から1を減じた値を変数 $l に代入している。

26行目の for 文は繰り返し処理を行う。
一般的に、for (式1; 式2; 式3) 文 の形で用いられ、初期値が (式1) で、(式2) が真である間、(文) を実行し、(式3) を実行する。
26行目では、変数 $i が0から始まり、$i が $l 未満である間、27~28行目を実行、$i を1だけ増やす($i++)処理を行う。

27行目では、0以上 $l 以下の乱数を発生させ、$n に代入する。
28行目で、関数 substr を使っているが、この関数は与えられた文字列から部分文字列を取り出すものである。ここでは、文字列 $str の $n 番目から1文字だけ取り出して、変数 $ch に代入している。これは、すなわち、パスワードに使用する文字種から任意の文字を1文字だけ取り出すことを意味する。

そして、変数 $ch をパスワード文字列 $psw の後に結合させるという処理を、指定した長さ(回数)になるまで for 文によって繰り返し実行している。
プログラムの評価

ただし、ここで生成されたパスワードは、ネットワーク上を平文で流れるので、盗聴は可能である。それを防ぎたいのであれば、SSLなどの暗号化を別途用意する必要がある。
参考サイト
- PHPとは何か/各バージョンのサポート期限:ぱふぅ家のホームページ
- PHPで覚えやすいパスワードを作る:ぱふぅ家のホームページ
- 強いパスワードをつくる:ぱふぅ家のホームページ
- PHPでパスワードの強度を調べる:ぱふぅ家のホームページ
- C++ でパスワード生成機を作る:ぱふぅ家のホームページ
- PHPセキュリティ対策:パスワード処理:ぱふぅ家のホームページ

まず最初に、パスワードを生成するプログラムをつくってみることにする。