2026年10月8日(木)掲載 4,871件/本日 0件
HN163

「乱数」が実はランダムじゃなかった時の話:疑似乱数の落とし穴と対策

When random is not actually random enough

steveklabnik・1日前

議論

3件
0:steveklabnikスレ主▲161日前

システムの開発において、「とりあえず乱数を使っておけばOK」と思っていませんか?実は、標準ライブラリの疑似乱数生成器(PRNG)は、セキュリティやシミュレーションのような高い精度が求められるケースでは、そのランダム性が十分ではないことが多々あります。乱数の偏りや周期性に泣かないために、適切なライブラリの選定や、暗号学的に安全な乱数生成(CSPRNG)の使い分けについて深掘りしていきましょう。

1:wilbo約23時間前

OPが10個の整数から3つの選択肢を選ぶ話をしていたあたりで混乱しちゃったけど、説明に何が欠けていたのかやっとわかった気がする。random_u64() Mod 3だと、確かに1つだけバケツが大きくなりすぎるよね。そのせいで1つの選択肢が5×10^-20くらい過剰に重み付けされちゃう。rand()自体も32767通りの値しかとれないから、バケツの数によってはどれかが偏るのがよくある話だね。

2:tialaramex約23時間前

こういう時に本当に必要なのは棄却サンプリングだよ:https://en.wikipedia.org/wiki/Rejection_sampling 。Wikiを見ると難しそうに書いてあるけど、今回の目的なら実装は笑えるくらいシンプルで済むよ。そのおかげで、なぜ動いているのかが明確だし、自信を持ってしっかりメンテナンスできるのがメリットだね。十分な大きさの入力を取得して、例えば2から11までの整数を選びたいなら、ニブル(半バイト)で十分。で、そのランダムな入力が欲しい範囲内にあるか確認して、範囲内ならそれが答え。もし範囲外なら、その値は捨てて新しく取得し直せばいい。プログラマーって、乱数を貴重なリソースか何かだと考えすぎなんだよね。