Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】Random\Engine\Mt19937::generate()メソッドの使い方

generateメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

generateメソッドは、PHPのRandom\Engine\Mt19937クラスにおいて、高品質な擬似乱数のバイト列を生成するメソッドです。このメソッドは、世界中で広く利用されている「メルセンヌ・ツイスター」という強力な擬似乱数生成アルゴリズムに基づいて動作します。擬似乱数とは、完全に予測不可能な真の乱数ではなく、特定の初期値(シード)から計算によって生成される、統計的にランダムに見える数列のことです。

具体的には、generateメソッドが呼び出されるたびに、このエンジンが管理する内部の状態が更新され、その結果として、システムで利用可能な最も大きな符号なし整数のサイズに相当する長さのバイト列を文字列として返します。例えば、64ビットシステムでは8バイトの文字列が生成されます。この生成されたバイト列は、より具体的な整数値や浮動小数点数を生成するための基盤となる、生のランダムなデータとして機能します。

システムエンジニアを目指す初心者の方にとっては、直接このメソッドを呼び出す機会は少ないかもしれません。通常は、PHP 8から導入されたRandom\Randomizerクラスを通じて、より簡単に特定の範囲の整数やシャッフルされた配列などを扱うことが推奨されます。しかし、Random\Engine\Mt19937クラスのgenerateメソッドは、そのような上位の機能が内部で利用している、根幹となる擬似乱数生成の仕組みを提供しています。ゲーム開発やシミュレーションなど、予測不能な要素が必要な場面で、信頼性の高い乱数を生成するために不可欠な役割を担っています。

構文(syntax)

1<?php
2$engine = new Random\Engine\Mt19937();
3$randomBytes = $engine->generate();

引数(parameters)

引数なし

引数はありません

戻り値(return)

string

指定された範囲のランダムなバイト列を64進数エンコードされた文字列として返します。

サンプルコード

PHP Mt19937 generate random string

1<?php
2
3/**
4 * Random\Engine\Mt19937::generate() メソッドを使用して、
5 * 乱数エンジンの生データから16進数文字列を生成します。
6 *
7 * generate() メソッドは引数なしで呼び出され、乱数エンジンが生成する
8 * 生のバイナリ文字列を返します。このバイナリ文字列は、通常は直接表示するよりも
9 * より高レベルな乱数生成器の基盤として利用されます。
10 *
11 * ここでは、バイナリ文字列を人間が読める16進数文字列に変換して表示することで、
12 * `generate()` が返すデータの形式を理解しやすくしています。
13 *
14 * @return string 生成された生の乱数データの16進数表現
15 */
16function getRandomHexStringFromMt19937(): string
17{
18    // Mersenne Twister (MT19937) 乱数エンジンの新しいインスタンスを作成します。
19    $engine = new Random\Engine\Mt19937();
20
21    // engineオブジェクトのgenerate()メソッドを呼び出します。
22    // このメソッドは、エンジンの現在の状態に基づいて、生のバイナリ文字列を返します。
23    $randomBinaryString = $engine->generate();
24
25    // 生のバイナリ文字列は、表示できない文字を含む可能性があるため、
26    // bin2hex() を使用して人間が読める16進数文字列に変換します。
27    return bin2hex($randomBinaryString);
28}
29
30// 関数を呼び出し、生成された16進数形式の乱数データを表示します。
31echo "Generated raw random data from Mt19937 engine (hexadecimal): " . getRandomHexStringFromMt19937() . PHP_EOL;
32

このPHPコードは、PHP 8で導入された新しい乱数生成機能の一部であるRandom\Engine\Mt19937クラスと、そのgenerate()メソッドの使い方を示しています。Random\Engine\Mt19937は、コンピュータで擬似乱数を生成するための代表的なアルゴリズムであるメルセンヌ・ツイスターに基づいた乱数エンジンです。

generate()メソッドは、この乱数エンジンのインスタンスから、現在の状態に基づいて「生のバイナリ文字列」を生成し、返します。このメソッドは引数を一切取りません。戻り値はstring型ですが、これは表示に適さないバイナリデータを含むため、通常は直接出力せず、より高度な乱数生成器の基盤として使用されます。

サンプルコードでは、この生のバイナリデータをbin2hex()関数を使って16進数文字列に変換しています。これにより、generate()メソッドが実際にどのようなデータを生成しているかを、人間が視覚的に確認できるようになります。このコードは、Random\Engine\Mt19937エンジンから生の乱数データを取得し、それを16進数形式で表示する一連の流れを具体的に示しています。

Random\Engine\Mt19937::generate()メソッドは、生のバイナリ文字列を返します。この文字列は通常、直接表示すると文字化けする可能性があるため、サンプルコードではbin2hex()関数を用いて、人間が読める16進数形式に変換している点にご注意ください。

このメソッド自体は、乱数エンジンの「生データ」を生成するものであり、特定の書式に整形されたランダムな文字列を直接生成するものではありません。そのため、目的のランダム文字列を得るには、用途に応じて追加の変換や加工が必要になります。

また、Mt19937は「擬似乱数」エンジンであり、暗号学的な安全性が求められる場面、例えばパスワードやセキュリティトークンの生成には適していません。高い安全性を要する用途では、PHP 8で導入されたRandom\Engine\Secureなど、より強力で安全な乱数生成器の使用を検討してください。

PHP 8 Random\Engine\Mt19937 で UUID を生成する

1<?php
2
3/**
4 * Random\Engine\Mt19937 を使用して Version 4 UUID を生成する関数。
5 *
6 * システムエンジニアを目指す初心者の方へ:
7 * この関数は、PHP 8 で導入された擬似乱数生成器 (Mersenne Twister) である
8 * Random\Engine\Mt19937 を乱数源として利用し、UUID (Universally Unique Identifier)
9 * の Version 4 形式の文字列を生成します。
10 *
11 * 注意: Mt19937 は擬似乱数生成器であり、暗号学的に安全ではありません。
12 * セキュリティが重要な UUID (例: セッショントークン、認証トークン) には、
13 * PHP の `random_bytes()` 関数、または `Random\Engine\Secure` エンジンを
14 * `Random\Randomizer` と組み合わせて使用することを強く推奨します。
15 * このサンプルは、リファレンス情報に指定されたエンジンを使用する目的で作成されています。
16 *
17 * @return string RFC 4122 に準拠した Version 4 UUID 文字列。
18 */
19function generateUuidUsingMt19937(): string
20{
21    // 1. Random\Engine\Mt19937 の新しいインスタンスを作成します。
22    // これが乱数の基となるエンジンです。
23    $engine = new Random\Engine\Mt19937();
24
25    // 2. Random\Randomizer インスタンスを作成し、上記で作成したエンジンを渡します。
26    // Randomizer は、このエンジンを利用してより柔軟な乱数生成機能を提供します。
27    $randomizer = new Random\Randomizer($engine);
28
29    // 3. UUID の生成に必要な16バイト(128ビット)のランダムなバイト列を取得します。
30    // Randomizer が内部で Mt19937 エンジンを使用してバイト列を生成します。
31    $bytes = $randomizer->getBytes(16);
32
33    // 4. 取得したバイト列を Version 4 UUID 形式にフォーマットします。
34    // UUID は特定のビットがバージョン情報とバリアント情報を持つように定められています。
35
36    // バイト列を個々のバイトに分解し、ビット操作できるようにします。
37    $data = str_split($bytes, 1);
38
39    // UUID のバージョンを 4 に設定します。
40    // 7番目のバイト(0-indexed で 6)の上位4ビットを '0100' (16進数で 4) に設定します。
41    // 0x0F は下位4ビットを保持し、0x40 は上位4ビットを '0100' に設定します。
42    $data[6] = chr((ord($data[6]) & 0x0F) | 0x40);
43
44    // UUID のバリアントを RFC 4122 (10xx) に設定します。
45    // 9番目のバイト(0-indexed で 8)の上位2ビットを '10' に設定します。
46    // 0x3F は下位6ビットを保持し、0x80 は上位2ビットを '10' に設定します。
47    // (結果としてこのバイトの先頭の16進数は 8, 9, A, B のいずれかになります)
48    $data[8] = chr((ord($data[8]) & 0x3F) | 0x80);
49
50    // 操作されたバイト列を結合し、全体を16進数文字列に変換します。
51    $hex = bin2hex(implode('', $data));
52
53    // 16進数文字列を UUID 形式 (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) に整形して返します。
54    $uuid = sprintf(
55        '%s-%s-%s-%s-%s',
56        substr($hex, 0, 8),
57        substr($hex, 8, 4),
58        substr($hex, 12, 4),
59        substr($hex, 16, 4),
60        substr($hex, 20, 12)
61    );
62
63    return $uuid;
64}
65
66// この関数は単体で実行可能です。以下のように呼び出して UUID を生成できます。
67// echo generateUuidUsingMt19937();

このサンプルコードは、PHP 8で導入された新しい乱数生成機能であるRandom\Engine\Mt19937を利用して、UUID(Universally Unique Identifier)のVersion 4形式の文字列を生成する関数です。

Random\Engine\Mt19937は、メルセンヌ・ツイスターというアルゴリズムに基づいた擬似乱数生成器で、PHPで利用できる乱数エンジンの一つとして提供されています。この関数では、まずRandom\Engine\Mt19937のインスタンスを作成し、それをRandom\Randomizerクラスに渡して、UUIDの生成に必要な16バイトのランダムなバイト列を取得します。

次に、取得したバイト列に対して、Version 4 UUIDの形式に合わせるためのビット操作を行います。具体的には、UUIDのバージョンが「4」になるよう特定のバイトの上位ビットを固定し、またUUIDのバリアントタイプが「RFC 4122」に準拠するよう別のバイトの上位ビットを固定します。これらの操作を経て整形されたバイト列は、最終的にハイフンで区切られた16進数形式のUUID文字列として組み立てられます。

この関数は引数を取りません。戻り値は、xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxxのような形式で、RFC 4122に準拠したVersion 4 UUID文字列となります。

ただし、Random\Engine\Mt19937は擬似乱数生成器であり、暗号学的に安全ではありません。そのため、セッショントークンや認証トークンなど、セキュリティが非常に重要な用途でUUIDを生成する場合には、PHPが提供するrandom_bytes()関数や、より強力なRandom\Engine\SecureエンジンとRandom\Randomizerを組み合わせた方法の利用を強く推奨します。

このサンプルコードは、擬似乱数生成器であるRandom\Engine\Mt19937を用いてUUIDを生成しますが、Mt19937は暗号学的に安全ではありません。そのため、セッショントークンや認証トークンなど、セキュリティが非常に重要な用途でこの方法で生成されたUUIDを利用することは避けてください。これらの用途では、攻撃者によって乱数が予測される可能性があり、システムに脆弱性をもたらす恐れがあります。セキュリティ要件の高いUUIDを生成する際は、PHPが提供するrandom_bytes()関数、またはRandom\Engine\SecureエンジンとRandom\Randomizerを組み合わせて使用することを強く推奨いたします。このサンプルは、リファレンス情報に指定された特定のエンジンを使用する目的で作成されています。

関連コンテンツ

【PHP8.x】Random\Engine\Mt19937::generate()メソッドの使い方 | いっしー@Webエンジニア