実用ツール
乱数とは?乱数生成の仕組みと使い方を徹底解説
抽選やゲーム、暗号化、テストデータの生成など、乱数はさまざまな場面で使われています。しかし、コンピューターで生成される「乱数」は本当にランダムなのでしょうか?この記事では、乱数の基本概念から疑似乱数と真の乱数の違い、プログラミングでの実装方法まで詳しく解説します。
乱数とは
乱数(らんすう)とは、規則性がなくランダムに出現する数のことです。サイコロを振って出る目やコイン投げの結果のように、予測不可能な数値を指します。コンピューターサイエンスでは、乱数はセキュリティ、シミュレーション、ゲーム、統計処理など幅広い分野で不可欠な存在です。
疑似乱数と真の乱数
乱数には大きく分けて2種類あります。それぞれの特徴を理解することが重要です。
| 項目 | 疑似乱数(PRNG) | 真の乱数(TRNG) |
|---|---|---|
| 生成方法 | 数学的アルゴリズム | 物理現象(熱雑音、放射性崩壊等) |
| 予測可能性 | シード値が分かれば再現可能 | 予測不可能 |
| 生成速度 | 高速 | 比較的低速 |
| 再現性 | 同じシードで同じ系列を再現 | 再現不可能 |
| 用途 | ゲーム、シミュレーション、テスト | 暗号化、セキュリティ |
| 代表例 | メルセンヌ・ツイスタ、線形合同法 | ハードウェアRNG、RANDOM.ORG |
プログラミングでの乱数生成
主要なプログラミング言語での乱数生成方法を紹介します。
// JavaScript - 疑似乱数(セキュリティ用途には不向き) Math.random() // 0以上1未満の浮動小数点数 Math.floor(Math.random() * 100) // 0〜99の整数 // JavaScript - 暗号学的に安全な乱数(セキュリティ用途向け) crypto.getRandomValues(new Uint32Array(1))[0] // ブラウザ・Node.js両方で利用可能 // Python import random random.randint(1, 100) # 1〜100の整数(疑似乱数) import secrets secrets.randbelow(100) # 0〜99の整数(暗号学的に安全)
重要:Math.random()は暗号学的に安全ではありません。パスワード生成やトークン生成には必ずcrypto.getRandomValues()を使用してください。
活用シーン
| 分野 | 用途 | 推奨される乱数 |
|---|---|---|
| 抽選・くじ引き | 当選者の選出、景品の割り当て | 疑似乱数でOK |
| ゲーム | ダメージ計算、アイテムドロップ、マップ生成 | 疑似乱数でOK |
| テスト | テストデータの生成、ファジング | 疑似乱数でOK |
| 暗号化 | 暗号鍵の生成、IV(初期化ベクトル) | 暗号学的乱数が必須 |
| セキュリティ | パスワード生成、セッショントークン | 暗号学的乱数が必須 |
| 統計・シミュレーション | モンテカルロ法、確率分布のサンプリング | 疑似乱数でOK |
よくある質問
Math.random()は本当にランダムですか?
Math.random()は疑似乱数であり、内部的には決定的なアルゴリズム(多くのブラウザではxorshift128+)で生成されています。統計的には十分にランダムですが、シード値がわかれば再現可能なため、暗号用途には使えません。
乱数に偏りがあるか確認する方法は?
カイ二乗検定やコルモゴロフ-スミルノフ検定などの統計的検定を使って乱数の一様性を検証できます。簡易的には、大量の乱数を生成してヒストグラムを作成し、偏りがないか視覚的に確認する方法もあります。
特定の範囲の整数乱数を生成するには?
min〜maxの整数乱数は Math.floor(Math.random() * (max - min + 1)) + min で生成できます。例えば1〜6のサイコロなら Math.floor(Math.random() * 6) + 1 です。