より高速に、推測困難な一意なIDを生成する方法

PHPでは、一意なキーを生成を生成するのに、uniqid()があります。

これは現在時間をマイクロ秒単位にしたものを使用しています。
つまりランダムというより、重複のない一意な値となります。

戻り値は、『 4a4f513eb71b1 』のような半角英数字の13文字です。16進数文字なので、「0から9 aからf」です。

第一引数にはプレフィックス、第二引数には追加のエントロピーの使用の有無を渡すことができます。

第二引数はデフォルトは false になっていますが、trueにするとドット『 . 』と数字9文字が追加され、文字数が23文字になります。
『 4a4f5caadd40c2.19903592 』このような値です。

半角英数字のみにするにはsha1ハッシュ変換します。

sha1( uniqid( null , true ) )

sha1の戻り値は、40文字の半角英数字(0から9 aからf)です。

セッションクッキーなどの推測されては困るようなトークンに使用する場合には、いくつかの関数を組み合わせます。

例えば、プレフィックスにも uniqid() をつける方法があります。

sha1( uniqid( uniqid() , true ) )

これよりほかの乱数エントロピーを組み合わせたほうがより推測困難になります。

sha1( uniqid( rand() , true ) )

より高速にするためには、rand()よりもmt_rand()を使用します。

sha1( uniqid( mt_rand() , true ) )

これで推測困難なIDを高速に生成することができます。

サンプルコード

echo sha1( uniqid( mt_rand() , true ) );

とすると

46e1e7d630f1ff4d2ba8d9c295758df5

と返ります。

注意点

md5は衝突性(コリジョン)があることが証明されていて、セキュリティホールとなることが潜在的に存在します。
このためsha1を使用するほうがいいです。

md5は半角英数文字で構成されるため0から9、aからzの10+26文字=36文字と思っている人がいますが、これは間違いです。
md5は16進数32桁なので0から9、aからfの10+6文字=16文字
「16の32乗」通りです。
(2進数にすると128ビットになります)

同様にsha1は16進数40桁なので「16の40乗」通りです。
(2進数にすると160ビットになります)

第2引数にtrue を指定すると、sha1 ダイジェストは 20 バイト長のバイナリ形式の値を返します。
これはバイナリなので画面に表示させると文字化けのようになります。

関連記事

スポンサーリンク

都道府県を選択するときのサンプルコード (JISコード準拠)

ホームページ製作・web系アプリ系の製作案件募集中です。

上に戻る