Javaでランダムシードを選択するクロスプラットフォームの方法は何ですか?
-
02-07-2019 - |
質問
この回答を読んだ後: コレクションからランダムなサブセットを選択する最適な方法
不思議に思ったのですが、Javaでランダムシードをどのように選ぶのですか?
そして、System.currentTimeMillis()またはSystem.nanoTime()を使用すると言ってはいけません。理由を確認するには記事を読んでください。
これは難しい質問ですが、もっと難しくさせてください。インターネットに接続せずに、ユーザー入力を使用せずにランダムシードを生成する必要があるとしましょう(IE、GUIはありません)。また、クロスプラットフォームである必要があります(したがって、ハードウェアにアクセスするJNIはありません)。
ランダム性のソースとして監視できるJVM変数はありますか?
これを行うことはできますか?それとも不可能ですか?
解決
Uncommons Maths をご覧ください(完全開示:私が書いた)。 Javaの乱数で発生する問題のほとんどを解決するはずです。
それを使用しなくても、さまざまな SeedGenerator 実装。基本的に、デフォルトでは / dev / random が使用されます。それが存在しない場合(Windowsなど)、 random.org からデータをダウンロードしようとするか、 SecureRandom.generateSeed 。
SecureRandom.generateSeedは、プラットフォーム固有のものやインターネットに依存せずにできる最善の方法だと思います。
他のヒント
System.currentTimeMillis()
を、シードを生成するたびにインクリメントするグローバルカウンタと組み合わせます。 AtomicLong を使用します。カウンタの場合、効率とスレッドセーフで増分できます。
"結合" 「追加」という意味ではありません。または" xor"重複を取得するのは簡単すぎるからです。代わりに、ハッシュ。あなたは複雑になり、長いものとカウンターを例えば16バイトとMD5ですが、おそらく64ビットバージョンのAdler CRCまたは他の 64ビットCRC 。
ええと、その記事は、32ビットのシードは悪いが、64ビットのシードは良いと言っています。 System.currentTimeMillis()は64ビットのシードです。