ランダムな文字列を生成して、どれくらいの確率で重複するか?

今回はちょっとした実験です。

ユニークなファイル名を生成する関数「tempnam()」関数がPHPにはあるのですが、XAMP環境ではうまく動作しないと以前書きました。

そこで以下のようなユニーク文字列生成関数を作って使っています。

function tempName($length=8){
	// ファイル名で使う文字列を指定
	$str = "23456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ";
	// 文字数を取得
	$num = strlen($str);
	$tmp = "";
	// 引数で指定した分だけ繰り返し
	for($i = 0; $i < $length; $i++){
		// 0~文字数-1の数字からランダムで選択
		$index = rand(0, $num-1);
		// 文字列からランダムで指定した位置の一文字を取得して連結
		$tmp .= substr($str, $index, 1);
	}
	// 生成した文字を返す
	return $tmp;
}

tempnam()関数との違いは、完全なユニークにならないかもしれないこと。

tempnam()関数は、指定したディレクトリでユニークなファイル名を生成し、空のファイルを作成します。
でも、上記で作成した関数では、存在チェックを行っていないので、重複する可能性があります。
いったいどれくらいの文字数でいくつ作成したら重複するのか?を調べてみました。

チェックを行ったコードは以下の通りです。

$count = 0;
for($i=0;$i<100;$i++){
	$array = array();
	$result = array();
	for($j=0;$j<100;$j++){
		$array[] = tempName(※);
	}
	$result = array_unique($array);

	if(count($result) != 100) $count++;
}
echo $count;

単純にランダム文字列生成を100回繰り返して生成し、その中で重複しているものを取り除いた配列を用意します。($result)
その配列の個数が100でない場合を1回と数えて、それを100回繰り返してみました。($count)

さらに生成する文字数によっても重複率を出してみました。

「※」の部分に作成文字列数として2、4、6、8、10文字のランダムな文字列を5パターンで計測した結果が以下です。

100個のランダム文字列を生成し、100回繰り返した場合に重複が1件でもある場合の回数

100個作るくらいだと、4文字以上の文字列を作ればほぼ大丈夫そうですね。

ちなみに1000個作った場合だと、

1000個のランダム文字列を生成し、100回繰り返した場合に重複が1件でもある場合の回数

2文字のランダム文字列なんて、必ず重複してますw
4文字でも1000個作って100回繰り返すと5%前後は重複するようですね。(多いときは10回以上)

ということを踏まえると、ユニーク文字列を作る場合、例えば、

$str = date('Ymd')."-".tempName();

このようにして、文字列の頭に当日の日付の数字8桁が入るように指定して生成してやれば、
1日に1000個ファイル名として生成したとしても、8文字以上で作っていればほぼ問題なさそうですね。
それでも気になるようでしたら、倍の16文字ならまず大丈夫でしょう。(保障はできませんが・・・)

ちなみに、上記1000個を100回繰り返すのに、さくらのレンタルサーバ ライトで実行した結果、実行時間が80~100秒くらい処理にかかりました・・・文字列1000個を100回生成して、10回試行しましたからね・・・

【追記】

ちょっと気になったので調べたら、各レンタルサーバーで応答時間が相当違いました。

レンタルサーバー会社 プラン 応答時間
株式会社KDDIウェブコミュニケーションズ CPI
シェアード(共有) 約34秒
レンタルサーバーミニム
ミニマムプラン 約35秒
ヘテムル
約43秒
ファーストサーバ
ギガント2 約44秒
エクスビット パーソナル300メガ  約46秒
WebARENA
 - 約47秒
ロリポップ!
チカッパプラン 約52秒
さくらのレンタルサーバ
ライト 約85秒
サーバーカウボーイ 計測不能※
ITPARK (同上)

※タイムアウトしました。max_execution_timeが指定できなかった。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

投稿ナビゲーション