【PHP】Laravelのランダム文字列生成メソッドとランダムURL用文字列生成スニペット

著者:杉浦

【PHP】Laravelのランダム文字列生成メソッドとランダムURL用文字列生成スニペット

 最近、ほぼ素のPHPでURL用のランダム文字列生成機能を作ったところ後から見たLaravelのランダム文字列生成メソッドの実装に驚いたので紹介。加えてこのLaravelのランダム文字列生成メソッドを受けて作成した素のPHPのURL用ランダム文字列生成コードを紹介します。
 Laravelのランダム文字列生成メソッドは次の通りです。

    /**
     * Generate a more truly "random" alpha-numeric string.
     *
     * @param  int  $length
     * @return string
     */
    public static function random($length = 16)
    {
        $string = ''; // ランダム文字列が入る変数

        // 現在の文字列長$lenが要求される文字列長$length以下ならば繰り返し
        // 繰り返しはほぼなし. 理由は後述
        while (($len = strlen($string)) < $length) {
            $size = $length - $len; // ランダム文字列に必要な文字数を算出

            // $size長のランダムなバイト文字列を生成
            // random_bytesは貴重なPHP組み込みの暗号論的に安全なランダムな値生成関数
            /** @see https://www.php.net/manual/ja/function.random-bytes.php PHP: random_bytes - Manual */
            $bytes = random_bytes($size);

            // base64_encode関数によってバイト文字列をbase64へ変換. base64は[0-9a-zA-Z/+=]の64と1文字のみで形成される文字列
            // base64へ変換された文字列から多くの場面で邪魔になる記号文字である/, +, =を削る
            // この文字を削る処理によって繰り返しが必要になる確率が極僅かながら存在する(基本base64による文字列の伸びの方が強い)。
            // base64によって伸びすぎた文字列をsubstr関数によって切り詰める
            // 切り詰めた必要な長さ(あるいはそれ以下)のランダム文字列を返り値用の引数$stringに連結して格納
            $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size);
        }

        return $string;
    }

 いざ実装コードを見てみると確かにこれ以上はPHP自体がstr_random関数を実装するぐらいしかないように思えます。乱数の種がいらず、長さを自由に決められて、ダブりがまず起きない、というのは本当にありがたいです。 これだけでも便利なのですが、URLでまず問題なく用いることのできる文字列は[0-9a-zA-Z]でなく[0-9a-z]と-と_の38文字と少々要求とrandom()が異なります。このあたりと上記コードを考慮すると次のコードが書けます。

$size = 32; // ランダム文字列の長さ
// 記号を_に置き換えるので文字列長が足りなくなる場合はなし。
// base64の仕様上確実に要求される文字列長よりエンコード後の文字列が長く=はカットされる
// 大文字のアルファベットをstrtolower関数によって小文字にする
$string = strtolower(substr(str_replace(['/', '+'], ['_', '-'], base64_encode(random_bytes($size))), 0, $size));

 用途を限定したためほぼ一行で済む様になりました。ダブルクリックで一発選択をしたい場合は[‘_’, ‘-‘]を’_’に書き換えるとよいです。

  • この記事いいね! (0)

著者について

杉浦 administrator