記事内にはプロモーションが含まれています

【PHP】ランダムな文字列を生成する方法(パスワードやユニークIDなど)

【PHP】ランダムな文字列を生成する方法(パスワードやユニークIDなど) PHP

Webアプリケーション開発において、ランダムな文字列を生成したい場面は頻繁に訪れます。

「ユーザーの仮パスワードを自動生成したい」
「アップロードされたファイル名が被らないようにランダムな名前にしたい」
「CSRFトークンを作りたい」

など、目的は様々です。

しかし、PHPには randmt_randuniqidrandom_bytes など、ランダムな値を生成する関数がいくつもあり、「結局どれを使えばいいの?」と迷ってしまうことも少なくありません。

この記事では、PHPでランダムな文字列を生成するための主要な方法を、セキュリティレベルや用途(パスワード、ID、テストデータなど)に合わせて分類し、現在の推奨される書き方をサンプルコード付きで徹底解説します。

【本記事の信頼性】
プロフィール
執筆者:マヒロ
  • 執筆者は元エンジニア
  • SES⇒大手の社内SE⇒独立
  • 現在はこじんまりとしたプログラミングスクールを運営
  • モットーは「利他の精神」

セキュリティ重視!暗号学的に安全なランダム文字列の生成

パスワードやトークン、セッションIDなど、予測されては困る重要なデータを扱う場合は、必ず 「暗号学的に安全な」 方法でランダム文字列を生成する必要があります。

randmt_randstr_shuffle は予測可能なため、セキュリティ用途には適していません。

推奨:random_bytes と bin2hex を使う方法

PHP 7以降で標準実装されている random_bytes 関数を使うのが、現在最も確実で安全な方法です。

生成されたバイナリデータを bin2hex で16進数の文字列に変換します。

<?php
// 16バイトのランダムなバイナリを生成し、32文字の16進数文字列に変換
$token = bin2hex(random_bytes(16));

echo "生成されたトークン: " . $token;
?>

実行結果

生成されたトークン: a3f9e2b1c8d7e6f5a4b3c2d1e0f9a8b7

random_bytes(16) は、予測不可能な16バイトのデータを生成します。

これを bin2hex に通すことで、「0-9」と「a-f」からなる32文字の文字列(1バイトあたり2文字になるため)が得られます。

CSRFトークンや一時的なAPIキーの発行には、この方法がベストプラクティスです。

任意の文字種(英数字など)でランダム文字列を作る

「パスワードに使いたいので、英数字と記号を混ぜたい」「大文字と小文字を含めたい」といった場合、random_int 関数を使って文字をランダムにピックアップする方法が推奨されます。

安全かつ柔軟な文字列生成関数

<?php
/**
 * 指定した長さのランダム文字列を生成する関数
 * @param int $length 生成する文字列の長さ
 * @return string
 */
function generateRandomString($length = 10) {
    // 使用する文字の定義
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $max = strlen($chars) - 1;
    $result = '';

    for ($i = 0; $i < $length; $i++) {
        // random_int は暗号学的に安全な整数を返す
        $index = random_int(0, $max);
        $result .= $chars[$index];
    }

    return $result;
}

// 12文字のパスワードを生成
echo "パスワード: " . generateRandomString(12);
?>

実行結果

パスワード: Xy7zA9bC1dEf

$chars 変数に、使いたい文字(英小文字、大文字、数字など)をすべて定義します。

ループの中で random_int(0, 最大インデックス) を使い、ランダムに1文字ずつ取り出して結合しています。

random_intrandom_bytes と同様に安全な関数なので、パスワード生成にも安心して利用できます。

簡易的なランダム文字列(テストデータやファイル名など)

セキュリティをそこまで気にしなくて良い場面、例えば「テスト用のダミーデータ」や「一時的なファイル名の生成」であれば、より手軽な方法も使えます。

str_shuffle を使う方法

str_shuffle は、渡された文字列をランダムにシャッフルする関数です。
これと substr(文字の切り出し)を組み合わせることで、簡単にランダム文字列が作れます。

<?php
// 文字列を定義してシャッフルし、先頭から8文字切り出す
$randomStr = substr(str_shuffle('1234567890abcdefghijklmnopqrstuvwxyz'), 0, 8);

echo "簡易ID: " . $randomStr;
?>

実行結果

簡易ID: 5a9b2c1d

ただし、この方法は非常に高速でコードも短いですが、生成される乱数の質が低く、予測されやすいという欠点があります。

あくまで「被らなければいい」「一時的なもの」として割り切って使いましょう。

ユニークID(一意な識別子)を生成する uniqid

「重複する可能性が極めて低いIDが欲しい」という場合は、現在時刻(マイクロ秒)に基づいてIDを生成する uniqid 関数が便利です。

uniqid の基本的な使い方

<?php
// 通常のuniqid(13文字)
echo "ID (通常): " . uniqid() . "\n";

// 接頭辞(prefix)を付ける
echo "ID (接頭辞): " . uniqid("user_") . "\n";

// エントロピー(乱数)を追加して独自性を高める(23文字)
echo "ID (高精度): " . uniqid("", true) . "\n";
?>

実行結果

ID (通常): 65a1b2c3d4e5f
ID (接頭辞): user_65a1b2c3d4e5f
ID (高精度): 65a1b2c3d4e5f1.23456789

uniqid() は時間をベースにしているため、同じ瞬間に実行されない限り重複しません。

第二引数を true にすると、乱数が追加されてさらに重複の可能性が低くなります。

データベースの主キー(ID)の代わりや、画像アップロード時のファイル名決定によく使われます。

PHPのスキルを活かして年収を上げる方法

以上、PHPでランダムな文字列を生成する方法について解説してきました。

なお、PHPのスキルがある場合には、「転職して年収をアップさせる」「副業で稼ぐ」といった方法を検討するのがおすすめです。

PHPエンジニアの需要は非常に高く求人数・案件数も多いため、転職によって数十万円の年収アップはザラで、100万円以上年収が上がることも珍しくありません。

なお、転職によって年収を上げたい場合は、エンジニア専門の転職エージェントサービスを利用するのが最適です。

今すぐ転職する気がなくとも、とりあえず転職エージェントに無料登録しておくだけで、スカウトが届いたり、思わぬ好待遇の求人情報が送られてきたりするというメリットがあります。

併せて、副業案件を獲得できるエージェントにも登録しておくと、空いている時間を活かして稼げるようなPHPの案件を探しやすくなります。

転職エージェントも副業エージェントも、登録・利用は完全無料なので、どんな求人や副業案件があるのか気になる方は、気軽に利用してみるとよいでしょう。