PHP8.2 で登場した乱数生成器を使った 1 〜 100 までの乱数を Seed 値で固定するときの対応表
はじめに
PHP8.2 から乱数生成に関して大きなアップデートがありました.
ランダムな値を生成する Random\Engine
というインタフェースがあり,それを用いて乱数を生成する Random\Randomizer
というクラスができました.
詳しくは以下の記事が参考になると思います(丸投げ)
また,PHP がネイティブで提供する Engine として,以下の 4 つがあります
Random\Engine\Mt19937::class
Random\Engine\PcgOneseq128XslRr64::class
Random\Engine\Xoshiro256StarStar::class
Random\Engine\Secure::class
例えば,1 〜 10 のランダムな整数を生成したい場合次のように書くことができます
$engine = new Random\Engine\Secure();
$randomizer = new Random\Randomizer($engine);
$randomizer->getInt(1, 10);
これら 4 種類の Engine のうち,Secure 以外の 3 つは Seed 値をコンストラクタに渡すことができ,外側から乱数生成をコントロールできます.
$engine = new Random\Engine\Mt19937(3);
$randomizer = new Random\Randomizer($engine);
$randomizer->getInt(1, 10); // seed 値 3 に対応する何かが固定で出てくる
このように Seed 値を固定してやれば,$randomizer->getInt(1, 10)
は何度実行しても同じ値を返します.
とはいえ,「この Seed 値を渡せばこの整数が出てくる」みたいな対応表や逆算方法はありません.
本記事では,差し当たり 1 〜 100 までの整数を生成する Seed 値を,3 種類の各 Engine 毎に愚直に求めましたので,その方法と実際に出した対応表を紹介します.
Seed 値と生成される整数の対応表の算出方法
例として,Random\Engine\Mt19937::class
を使った場合のコードを示します.
// Random\Engine\Mt19937 で 1 ~ 100 の値を固定で出すシード値を計算
$map = [];
for ($seed = 0; $seed < 10000; ++$seed) {
$randomInt = (new \Random\Randomizer(new \Random\Engine\Mt19937($seed)))->getInt(1, 100);
if (!isset($map[$randomInt])) { // まだ出てなければ整数と Seed 値の組を保存
$map[$randomInt] = $seed;
}
// 100 まで集まったらループ終了
if (count($map) === 100) {
break;
}
}
ksort($map); // 1 -> 100 の順になるように並び替える
要は,とりあえず 10000 回くらいぶん回してみて虱潰しに探していくという方法です.
1 〜 100 までのランダムな整数なので,試行回数 10000 回くらい回せばきっと全種類出てくれるよね,という楽観的な発想です.
実際,php-src の実装でも,同じような方法を使ってロジックのテストを書いている箇所がありました.
対応表
乱数を固定したテストをするときにでもお役立てください
Random\Engine\Mt19937
整数 | Seed 値 |
---|---|
1 | 111 |
2 | 60 |
3 | 248 |
4 | 120 |
5 | 50 |
6 | 132 |
7 | 18 |
8 | 45 |
9 | 249 |
10 | 76 |
11 | 95 |
12 | 5 |
13 | 201 |
14 | 116 |
15 | 24 |
16 | 7 |
17 | 66 |
18 | 35 |
19 | 13 |
20 | 67 |
21 | 160 |
22 | 149 |
23 | 126 |
24 | 8 |
25 | 105 |
26 | 145 |
27 | 31 |
28 | 80 |
29 | 48 |
30 | 56 |
31 | 4 |
32 | 20 |
33 | 15 |
34 | 46 |
35 | 242 |
36 | 14 |
37 | 41 |
38 | 10 |
39 | 40 |
40 | 27 |
41 | 75 |
42 | 11 |
43 | 42 |
44 | 247 |
45 | 0 |
46 | 1 |
47 | 114 |
48 | 153 |
49 | 2 |
50 | 26 |
51 | 51 |
52 | 82 |
53 | 241 |
54 | 21 |
55 | 74 |
56 | 47 |
57 | 165 |
58 | 142 |
59 | 91 |
60 | 17 |
61 | 226 |
62 | 688 |
63 | 141 |
64 | 12 |
65 | 118 |
66 | 36 |
67 | 115 |
68 | 131 |
69 | 33 |
70 | 130 |
71 | 9 |
72 | 89 |
73 | 63 |
74 | 78 |
75 | 70 |
76 | 81 |
77 | 150 |
78 | 28 |
79 | 62 |
80 | 90 |
81 | 72 |
82 | 16 |
83 | 73 |
84 | 437 |
85 | 88 |
86 | 29 |
87 | 3 |
88 | 129 |
89 | 43 |
90 | 22 |
91 | 49 |
92 | 23 |
93 | 25 |
94 | 59 |
95 | 124 |
96 | 103 |
97 | 139 |
98 | 30 |
99 | 98 |
100 | 68 |
Random\Engine\PcgOneseq128XslRr64
整数 | Seed 値 |
---|---|
1 | 43 |
2 | 319 |
3 | 76 |
4 | 14 |
5 | 4 |
6 | 69 |
7 | 53 |
8 | 25 |
9 | 15 |
10 | 16 |
11 | 162 |
12 | 174 |
13 | 112 |
14 | 126 |
15 | 42 |
16 | 80 |
17 | 101 |
18 | 73 |
19 | 9 |
20 | 24 |
21 | 11 |
22 | 113 |
23 | 275 |
24 | 160 |
25 | 37 |
26 | 44 |
27 | 71 |
28 | 32 |
29 | 39 |
30 | 46 |
31 | 31 |
32 | 195 |
33 | 143 |
34 | 36 |
35 | 286 |
36 | 66 |
37 | 22 |
38 | 6 |
39 | 19 |
40 | 78 |
41 | 662 |
42 | 20 |
43 | 116 |
44 | 28 |
45 | 56 |
46 | 75 |
47 | 7 |
48 | 2 |
49 | 191 |
50 | 21 |
51 | 34 |
52 | 335 |
53 | 74 |
54 | 45 |
55 | 57 |
56 | 13 |
57 | 89 |
58 | 94 |
59 | 345 |
60 | 154 |
61 | 68 |
62 | 5 |
63 | 49 |
64 | 361 |
65 | 314 |
66 | 123 |
67 | 29 |
68 | 52 |
69 | 82 |
70 | 35 |
71 | 72 |
72 | 139 |
73 | 3 |
74 | 0 |
75 | 8 |
76 | 96 |
77 | 237 |
78 | 41 |
79 | 61 |
80 | 23 |
81 | 60 |
82 | 324 |
83 | 95 |
84 | 48 |
85 | 18 |
86 | 150 |
87 | 30 |
88 | 165 |
89 | 122 |
90 | 183 |
91 | 118 |
92 | 50 |
93 | 47 |
94 | 528 |
95 | 1 |
96 | 10 |
97 | 97 |
98 | 362 |
99 | 393 |
100 | 117 |
Random\Engine\Xoshiro256StarStar
整数 | Seed 値 |
---|---|
1 | 33 |
2 | 30 |
3 | 304 |
4 | 52 |
5 | 20 |
6 | 27 |
7 | 73 |
8 | 11 |
9 | 31 |
10 | 87 |
11 | 7 |
12 | 92 |
13 | 74 |
14 | 47 |
15 | 42 |
16 | 8 |
17 | 365 |
18 | 10 |
19 | 153 |
20 | 234 |
21 | 292 |
22 | 49 |
23 | 116 |
24 | 39 |
25 | 81 |
26 | 65 |
27 | 13 |
28 | 178 |
29 | 37 |
30 | 235 |
31 | 121 |
32 | 23 |
33 | 276 |
34 | 106 |
35 | 44 |
36 | 72 |
37 | 298 |
38 | 129 |
39 | 114 |
40 | 282 |
41 | 98 |
42 | 107 |
43 | 150 |
44 | 291 |
45 | 43 |
46 | 118 |
47 | 255 |
48 | 97 |
49 | 32 |
50 | 12 |
51 | 143 |
52 | 148 |
53 | 145 |
54 | 5 |
55 | 41 |
56 | 34 |
57 | 38 |
58 | 6 |
59 | 17 |
60 | 64 |
61 | 93 |
62 | 51 |
63 | 19 |
64 | 90 |
65 | 68 |
66 | 18 |
67 | 26 |
68 | 25 |
69 | 3 |
70 | 58 |
71 | 180 |
72 | 2 |
73 | 251 |
74 | 21 |
75 | 151 |
76 | 392 |
77 | 59 |
78 | 132 |
79 | 103 |
80 | 61 |
81 | 89 |
82 | 232 |
83 | 104 |
84 | 15 |
85 | 69 |
86 | 162 |
87 | 117 |
88 | 256 |
89 | 141 |
90 | 91 |
91 | 200 |
92 | 4 |
93 | 0 |
94 | 14 |
95 | 57 |
96 | 229 |
97 | 36 |
98 | 1 |
99 | 22 |
100 | 182 |
スペシャルサンクス
今回の方法をアドバイスしてくれた mpyw さん
Discussion