PHPプログラミング

ベストプラクティス

数値の扱い

暗号化でも安全に使える乱数を生成する:random_int関数

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

特定の範囲でランダムな数値を、暗号学的にも信頼できる方法で取得することができるrandom_int関数について解説します。php5.6以前で使用する方法も併せて解説。

目次

  1. #  random_int関数とmt_rand関数の違い
  2. #  random_int関数の基本的な使い方
  3. #  PHPバージョン5.6以前での使い方
  4. #  配列と組み合わせてランダムな文字列を生成する

random_int関数とmt_rand関数の違い

PHPでは、特定の範囲で乱数を取得するのに便利なmt_rand関数というものがあります。
しかしこちらの関数で使用する乱数を発生させるアルゴリズムは、php.netにもある通り暗号学的に安全ではありません。

そこで今回は、パスワードの生成など暗号学的により安全な乱数を取得することができるrandom_int関数についての使用方法を解説していきます。
標準では、こちらの関数はphp7.0以降で使用可能な関数となっていますが、ライブラリを使って5.6以前のバージョンでも使用できる方法も解説します。

random_int関数の基本的な使い方

基本的な使い方は下記の通り。

random_int( 最小値, 最大値)

mt_rand関数と同様、乱数の最小値と最大値を指定して呼び出します。
mt_rand関数はこの2つの値を指定しなくても自動で設定してくれましたが、random_int関数は必ず指定する必要があります。

for文を使って、試しに10回連続で乱数を取得し出力するコードを書いてみましょう。

コード例

<?php

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

実行結果

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

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

PHPバージョン5.6以前での使い方

ライブラリを使うことで、PHP5.6以前でも同じようにrandom_int関数を使うことが出来ます。
paragonie/random_compat – GitHub

次のようにZIP形式でダウンロードして解凍し、libディレクトリを任意の場所に設置してください。

ZIPでダウンロードする流れ

今回はrandom_int関数を使用するファイルを「index.php」とし、次のような配置で使用していきます。

ライブラリの設置例

それでは、ライブラリを読み込んで関数を使ってみましょう。

コード例

<?php

require_once "lib/random.php";

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

実行結果

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

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

PHP7.0以降と同じように使うことが出来ました。

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

配列と組み合わせて、パスワードのようなランダムな文字列を生成してみます。
PHP5.6以前の場合は、最初にライブラリの読み込みを行うことで同じコードを実行することが出来ます。

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[random_int( 0, count($base_strings)-1)];
}

var_dump($res);

実行結果

string 'qv5Tr3wQBu' (length=10)

解説

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

以上、random_int関数の使用方法の解説でした。

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