PHPプログラミング

ベストプラクティス

数値の扱い

乱数を生成する:mt_rand関数

  • このエントリーをはてなブックマークに追加

特定の範囲でランダムな数値を取得したい時に便利なmt_rand関数の使用方法を解説します。

目次

  1. #  mt_rand関数の使い方
  2. #  rand関数とmt_rand関数の違い
  3. #  文字列と組み合わせてランダムな文字列を生成する

mt_rand関数の使い方

mt_rand関数はパラメータなしで呼び出すか、最小値と最大値の2つのパラメータを指定して実行します。

パラメータを指定しない

パラメータを指定しない場合は、0からmt_getrandmax関数で取得できる範囲の数値からランダムに数値を取り出します。
mt_getrandmax関数が返す数値は環境によって異なる可能性があるため、意図した範囲の数値を取得したい場合はパラメータを指定した方が確実です。

mt_rand();

こちらで実行した環境では、mt_getrandmax関数で取得した値が2147483647だったので、02147483647の間の値を取得できることになります。

コード例

for文でmt_rand関数を10回実行し、取得した乱数をvar_dump関数で出力してみます。

for( $i=0; $i<10; $i++ ) {
	var_dump( ($i+1) . " =>" . mt_rand());
}

実行結果

「=>」の左側が実行回数、右側が取得した乱数です。

string '1 =>1942190876' (length=14)
string '2 =>1086785960' (length=14)
string '3 =>1704596979' (length=14)
string '4 =>617295273' (length=13)
string '5 =>85946853' (length=12)
string '6 =>1957267170' (length=14)
string '7 =>2022904355' (length=14)
string '8 =>630493920' (length=13)
string '9 =>42652825' (length=12)
string '10 =>1055468133' (length=15)

パラメータを指定する

続いて、取得する乱数の範囲を指定するパラメータを指定してみましょう。

mt_rand( 0, 10);

パラメータを1つしか指定しなかった場合はnullが返されます。
また、2つ目より1つ目のパラメータの数値が大きい場合はfalseが返されます。

コード例

取得する乱数の範囲を010と指定し、for文で10回実行してみます。

for( $i=0; $i<10; $i++ ) {
	var_dump( ($i+1) . " =>" . mt_rand( 0, 10));
}

実行結果

string '1 =>1' (length=5)
string '2 =>4' (length=5)
string '3 =>10' (length=6)
string '4 =>10' (length=6)
string '5 =>10' (length=6)
string '6 =>1' (length=5)
string '7 =>8' (length=5)
string '8 =>1' (length=5)
string '9 =>9' (length=5)
string '10 =>0' (length=6)

rand関数とmt_rand関数の違い

同じ乱数を取得できるrand関数があります。
関数の使い方も同じでどちらを使えばいいのか紛らわしいのですが、mt_rand関数の方が高速に動作するため、mt_rand関数を使うようにしましょう。

PHP7.1以降では、rand関数mt_rand関数のエイリアスとなり実質同じものとなりました。
rand関数を呼び出しても実際にはmt_rand関数が実行されます。

配列と組み合わせてランダムな文字列を生成する

mt_rand関数と配列を組み合わせて、パスワードのようなランダムな文字列を生成してみましょう。

randomString.php

// 変数の初期化
$res = null; //生成した文字列を格納
$string_length = 10; //生成する文字列の長さを指定
$base_strings = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0,1,2,3,4,5,6,7,8,9];

for( $i=0; $i<$string_length; $i++ ) {
	$res .= $base_strings[mt_rand( 0, count($base_strings)-1)];
}

var_dump($res);

$base_stringsには大文字・小文字のアルファベットと数字が入っています。
そこで、mt_rand関数を使って0〜(配列の長さ−1)の範囲で乱数を取得することで、ランダムな1文字を取得する仕組みです。
その処理を$string_lengthで指定した回数だけ実行し、任意の長さのランダムな文字列を取得しています。

以上の処理でパスワードのような文字列を生成できますが、php.netに記載のある通りmt_rand関数は暗号学的には安全ではないとされています。
そのため、パスワードの自動生成として使うことはオススメしません。
パスワードとして使うランダムな文字列を生成したい場合は、random_int関数を使うようにしてください。

こちらの関数の使い方については「暗号化などで安全な乱数を生成する:random_int関数」をご覧ください。

  • このエントリーをはてなブックマークに追加