LoginSignup
1
1

More than 1 year has passed since last update.

Java の乱数発生器

Posted at

これは何?

Javaの乱数生成器について速度面から調査してみる
という記事を見て、Java の乱数にも色々あるんだなと思い。

速度面以外を軽く調べた。

調べた

java.util.Random

Knuth 先生の有名なアルゴリズムを使っている。
有名だけど、メルセンヌ・ツイスタなんかと比べるとバラケ具合がしょぼいこともよく知られている。

java.util.concurrent.ThreadLocalRandom

内部状態は

java
long rnd;

の一個、64bit だけ。定数が

java
long multiplier = 0x5DEECE66DL;
long addend = 0xBL;
long mask = (1L << 48) - 1;

と用意されていて計算は

java
int next(int bits) {
    rnd = (rnd * multiplier + addend) & mask;
    return (int) (rnd >>> (48-bits));
}

これだけ。bits はほしいビット数なので気分としては 32固定だと思っていいと思う。

実用的には困らない場面も多いとは思うけど、バラケ具合はあまり良くないと思う。

L??X??MixRandom

L32X64MixRandom のソースコードらしきもの を見ると

LXM ファミリの一員らしい。

M は、0xadb4a92d という値。
a は、コンストラクタで決まる奇数で。

xoroshiro64 で作られた乱数 x0 と、と $s=Ms+a$ で作られる系列 s の値を足したものを

java
public static int mixLea32(int z) {
    z = (z ^ (z >>> 16)) * 0xd36d884b;
    z = (z ^ (z >>> 16)) * 0xd36d884b;
    return z ^ (z >>> 16);
}

で混ぜたものらしい。

単なる xoroshiro64 だと弱いので別の乱数を混ぜた感じかな。

Xoroshiro128PlusPlus

中身は見てないけど、Xoroshiro128++ なんだろう。
Xoroshiro シリーズは https://prng.di.unimi.it/ を読むとなんだか分かる。

Xoshiro256PlusPlus

中身は見てないけど、Xoshiro256++ なんだろう。
Xoroshiro シリーズと同様、 https://prng.di.unimi.it/ を読むとなんだか分かる。

感想

メルセンヌ・ツイスタが無いのがちょっと意外。

最初に上げた記事では

個人的には、暗号やセッションキーの生成等ではSecureRandom。それ以外は通常ThreadLocalRandom。

となっているけど、私なら

  • 予測不能性が必要ない場面なら基本 Xoroshiro128PlusPlus または Xoshiro256PlusPlus。どっちか速い方。どっちが速いか知らない今調べずに使うなら Xoshiro256PlusPlus かな。
  • $2^{256}$ より長い周期が必要になったら LXM ファミリから選ぶ

かな。

とはいえ。
Java を使う機会自体がないのであった。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1