テストデータ生成ツールには、Seed(シード)という入力欄がよくあります。例えばSeedを42にして100件のデータを作り、あとでもう一度、同じ生成器・同じ処理条件でSeedを42にすると、同じデータを再現できることがあります。「ランダムなのに、なぜ同じ結果になるのか」と不思議に見えます。

理由は、コンピューターで使う乱数の多くが、完全に予測不能な値を毎回ゼロから作っているのではなく、決まった計算を繰り返して“ランダムに見える数列”を作る擬似乱数だからです。Seedはその計算をどこから始めるかを決めます。

再現できる仕組みを4つに分ける

PRNG

擬似乱数は計算で作る

見た目はばらばらでも、内部では決められた計算規則に従って次の値を作ります。同じ状態から始めれば、同じ計算結果になります。

Seed

Seedが出発点を決める

Seedは生成器の初期状態を決める材料です。同じSeedを同じ方法で初期化すれば、同じ数列をたどれます。

State

1回使うたび状態が進む

1個の値を取り出すたびに内部状態が変わります。途中で乱数を1回余分に使うだけでも、それ以降の値がずれることがあります。

Reproduce

条件を揃えると同じ結果になる

Seedだけでなく、アルゴリズム、設定、辞書、処理順も同じなら、同じランダムデータを再現しやすくなります。

ランダムに見えても、実際には決まった計算をしている

コンピューターで扱う乱数にはいくつか種類があります。テストデータやゲーム、シミュレーションなどでは、擬似乱数生成器(PRNG: Pseudo-Random Number Generator)がよく使われます。擬似乱数生成器は内部に状態を持ち、その状態から次の値を計算し、状態を更新して、また次の値を計算します。

重要なのは、この処理が決定的であることです。同じ内部状態に同じ計算を適用すれば、次に出る値も同じになります。人間には不規則に見える数列でも、生成器の側から見ると『前の状態から次の状態へ進んでいる』だけです。

Seedは『最初の乱数』ではなく、初期状態を作るための値

Seedは、擬似乱数生成器をどの状態から始めるかを決めるために使う値です。Seedそのものが、そのまま1個目の乱数になるとは限りません。多くの実装ではSeedを変換して内部状態を作り、そこから乱数列を生成します。

同じSeedを同じアルゴリズムへ渡し、同じ初期化方法を使えば、出発点が同じになります。その後も同じ順番で乱数を取り出せば、1個目、2個目、3個目……と同じ列を再現できます。

Seedから内部状態が進む流れ(概念図)
Seed 42 初期状態 S0 乱数① 状態 S1 乱数② 状態 S2 乱数③

途中で1回余分に乱数を使う → それ以降の値が1つずつずれる

テストデータでは、乱数列を各列の値へ変換している

テストデータ生成では、擬似乱数そのものをそのまま表示するのではなく、値を用途に合わせて変換します。ある乱数で氏名候補を選び、次の乱数で日付を選び、さらに次の乱数で欠損値を入れるか判断する、といった使い方です。

そのため、同じSeedだけでなく、列の並び、件数、各列の設定、候補辞書、欠損・境界・異常値の割合なども同じであることが重要です。同じ乱数列を使っていても、値へ変換するルールが変われば、最終的なデータは変わります。

同じSeedでも結果が変わるのはどんなとき?

Seedは再現性の中心ですが、Seedだけを保存すれば永久に同じ結果になるわけではありません。生成アルゴリズムを変更した、乱数を使う順番を変更した、途中で新しい列を追加して乱数を1回多く消費した、候補辞書を更新した、といった変更で結果はずれます。

別のライブラリや別の言語へSeedの数値だけを渡しても、同じ列になるとは限りません。JavaScriptのMath.random()も擬似乱数を返しますが、ECMAScript仕様ではアルゴリズムは実装依存で、利用者がSeedを指定・リセットする標準APIもありません。再現性が必要なアプリは、Seedを指定できる生成器を自前またはライブラリで用意するのが一般的です。

Seedがあると、バグを『もう一度起こす』ことができる

テストでSeedが便利なのは、偶然見つかった失敗を保存できるからです。例えば10万件のランダムデータで処理したとき、ある組み合わせだけで不具合が起きたとします。Seedと設定を記録しておけば、あとから同じ入力を作り直し、修正前と修正後を比べられます。

反対に、毎回完全に違うデータしか作れないと、『昨日は失敗したのに今日は再現しない』という状態になりやすくなります。Seedはランダム性をなくすためではなく、ランダムに探索した結果へ戻れるようにするための目印として使えます。

Browser Kittyのテストデータ生成では、Seedと設定をセットで扱う

Browser Kittyのテストデータ生成では、Seedを指定して同じ設定・件数から同じ生成結果を再現できます。Seedを空欄にした場合は生成時にSeedを作り、実際に使ったSeedを確認できます。また、件数・Seed・列設定を設定ファイルとして保存できます。

ここで大切なのは、Seedだけでなく設定も一緒に残すことです。『Seed 42で失敗した』だけより、『この列構成・この欠損率・この件数・Seed 42で失敗した』まで残した方が、テストケースとして再現しやすくなります。

再現できる乱数と、セキュリティ用の乱数は目的が違う

テストでは「あとから同じ値を出せる」ことが利点ですが、パスワード、セッショントークン、暗号鍵などでは、第三者が出力や内部状態から次の値を推測しにくいことが重要です。テスト用の一般的なPRNGは、そのような暗号学的な予測困難性を目的としていません。

そのため、テスト用のPRNGをセキュリティ用途へ流用しません。MDNもMath.random()を暗号学的に安全な乱数として使わず、必要な場合はWeb Crypto APIのCrypto.getRandomValues()などを使うよう案内しています。同じ「乱数」でも、テストでは再現性、セキュリティでは予測されにくさという別の性質が重要です。

同じデータを再現するために揃えたい4つ

Seed付きのテストデータをあとから再現したいときは、Seedだけでなく次の4つをセットで残すと安全です。

  1. Seed同じ初期状態へ戻るための値です。バグ報告やテストケースには実際に使用したSeedを残します。
  2. 生成器とバージョン擬似乱数生成アルゴリズムやアプリの実装が変わると、同じSeedでも列が変わる可能性があります。必要ならアプリのバージョンも記録します。
  3. 設定と辞書列定義、範囲、候補値、欠損率、境界値・異常値の割合など、乱数を最終データへ変換する条件も揃えます。
  4. 処理順と件数乱数を取り出す順番や回数が変わると内部状態の進み方も変わります。列順、生成件数、途中の追加処理も再現性へ影響します。
Browser Kittyで試す

テストデータ生成

列・件数・Seedを指定し、欠損・境界・異常値も混ぜた再現可能なテストデータをブラウザ内で生成します。

ツールを開くツールの詳細を見る

注意点

  • Seedは「ランダムさの強さ」を表す数字ではありません。大きいSeedだから、よりランダムになるわけではありません。

よくある質問

同じSeedなら、いつでも完全に同じデータになりますか?

Seedだけでは保証できません。同じ生成アルゴリズム、初期化方法、設定、候補データ、乱数を使う順番・回数などが揃っている必要があります。アプリの実装やバージョンが変われば、同じSeedでも結果が変わることがあります。

Seedを変えると、必ずまったく違うデータになりますか?

通常は別の乱数列になりますが、最終データに同じ値が一部含まれることはあります。例えば候補が『東京・大阪・名古屋』の3つだけなら、別のSeedでも同じ都市が選ばれる行は当然あり得ます。Seedが違うことと、すべての出力値が重複しないことは別です。

Math.random()にSeedを指定すればよいのですか?

標準のJavaScript APIではできません。Math.random()の初期Seedは実装側が選び、利用者が指定・リセットするAPIはありません。Seedで再現したい場合は、Seed指定に対応した擬似乱数生成器を別に使います。

Seedを保存しておけば、生成した100万件のデータを保存しなくてもよいですか?

同じ生成結果を再構築する目的なら、Seedと設定を保存する設計は有効です。ただし、生成ロジックや辞書、アプリのバージョンが変わると同じ結果にならない可能性があります。監査や証跡として当時のデータそのものが必要な場合は、Seedだけで代用できません。

Seed付きの擬似乱数をパスワード生成に使ってもよいですか?

テスト再現用の一般的なSeed付きPRNGを、そのままセキュリティ用途へ使うべきではありません。そうしたPRNGは、第三者が出力や内部状態から次の値を推測しにくいという暗号学的な安全性を目的としていません。Webでは用途に応じてWeb Crypto APIなどの暗号学的乱数を使います。

参考資料

擬似乱数、Seedによる再現性、JavaScriptのMath.random()、セキュリティ用途の乱数について、以下の仕様・公式ドキュメントを参照しています。Seedから同じ列を再現できる範囲は生成器や実装に依存するため、この記事では『同じSeedだけで永続的に同じ結果が保証される』とはしていません。