作成日:2024年09月11日
Random関数は本当にランダムか?


どうも、にゃん太です
乱数を利用した処理において、乱数が偏りなく作成されている事は重要です
今回のメモでは、乱数作成に使用するRandom関数の調査結果について書いていきます
先日ファイルメーカーで、簡易的な認証処理を作成しました
- ユーザーがメールアドレスを入力
- システムで6桁の数字列による認証コードを作成
- メールアドレス宛に認証コードを送信
- ユーザーが認証コードを入力
といった処理なのですが、生成した認証コードに同じ数字が3つ以上入っている率が非常に高い気がします
Random関数を使用して生成しているのですが、本当に乱数になっているのか疑問が生じたのでテストしてみたいと思います
乱数の生成
まずはRandom関数で乱数を生成してみます
計算タイプでは値が変わってしまう事がありますので、数字タイプのフィールドにスクリプトで値を入れます
スクリプト
# ################################################## # 乱数生成 # ################################################## ウインドウの固定 Loop [フラッシュ: 延期] Exit Loop If [Get ( 対象レコード数 ) ≥ 1000000] 新規レコード/検索条件 フィールド設定 [test::乱数1; Random] フィールド設定 [test::乱数2; Random] End Loop
これで乱数が生成されました
生成された乱数は有効桁数が20桁となっている様です
念のため重複チェックしましたが、重複値はありませんでした
乱数の分布をみる
では、先ほど作成した乱数の分布状況を見たいと思います
乱数1を折れ線グラフで見ると下図の様になります

特に明らかな偏りが見受けられませんが、細かい所はよく分かりません
今度は散布図で見てみましょう

空白部分が見え、あまり均等に割り当てられていない様ですが……、そもそも点が100万個ある様には見えず、おそらく処理限界を超えてしまっていると考えられます
グラフで見るのは限界の様です
では次に、0.1刻みでの生成数を見てみます

1%未満の誤差がありますが、概ね均等に生成されている様です
0.01刻みでの生成数ではどうでしょうか

ちょっと誤差がおおきくなりましたが、偏っているという程ではありません
少なくとも認証コードの生成処理を行う程度であれば、特に問題なく使用できそうです
では何故、6桁に同じ数字が3つ以上入るのか
上記の検証結果からすれば、6桁の数字の中に同じ数字が3つ以上入る原因は乱数の問題ではありませんでした
そこで、改めて「000000」から「999999」までに値の中に同じ数字が3つ含まれる場合がどれだけあるのかを調べてみました
その結果、何と157,600件が該当する事が分かりました
純粋に100万件から選んでいた訳ではありませんが、これだけの確率で存在しているなら気になる程度には発生してもおかしくなかったですね
Random関数くん、疑ってごめんなさい

以上で今日のメモ書きは終了です
内容はいかがでしたか?
もしご意見やご要望、誤りの指摘などありましたら、下記フォームよりお気軽にご連絡ください