手軽に使える乱数生成クラス

以下、cppll に投稿した内容と同文。

よくC/C++の標準の乱数関数はダメダメだと評価されてますけど、実際ダメダメなんで、以前から、ヘッダファイルをインクルードするだけでお手軽に使えるまともな乱数クラスを用意しようと思ってたんで作成してみました。

【乱数生成(RNG)モジュール ヘッダファイル】
http://tricklib.com/cxx/dagger/trickrng.h

# RNG == Random Number Generator

使い方は...

#include "trickrng.h"

void hoge()
{
  tricklib::secure_dice_type secure_dice;
  uint32_t secure_random_value = secure_dice.roll();

  tricklib::default_dice_type default_dice;
  uint32_t default_random_value = default_dice.roll();

  ...
}

...といった具合に使えます。このヘッダファイルで提供しているすべての乱数クラスは 0x00000000 から 0xFFFFFFFF の値域で乱数を生成します。

secure_dice_type は Windows 環境であれば Crypt API を利用した実装( win_secure_dice )になり、Linux/Unix 環境であれば /dev/urandom を利用した実装( unix_secure_dice )になり、ともに鍵生成などのセキュリティ用途で使用しても問題のないものです。

default_dice_type の実装( prime_spiral_dice )はこのモジュール用に書き下ろした疑似乱数アルゴリズムで以下のような特徴を持ちます(説明を簡単にするため一部、厳密には間違いを含む記述になっています)。

  • 周期は 2^32。
  • 固定の600バイトの乱数テーブルを使用する。
  • インスタンスのメモリ消費量は4バイト。
  • 乱数テーブルが知られていない状況であればそれまでの乱数値から次の乱数値を予測することはできない。逆に乱数テーブルが知られていれば一回分の乱数値で次回以降の乱数列を予測可能。
  • 出力された乱数列から乱数テーブルは逆算できない。
  • 出力される乱数列のばらつき具合は最上級に良質で、規則性も一切でない。
  • 0x00000000 から 0xFFFFFFFF の値がすべて出るとは限らず、一部出力されない値や重複して出力される値が発生する。
  • 一般的な疑似乱数アルゴリズムとしては鈍足。

...最後の点に関しては一般的な疑似乱数アルゴリズムとしては重いというだけで実際には、インクリメント+(除算+テーブル参照)×8+排他的論理和×7な演算しかしていないのでよほどシビアに速度が求められる場面以外では問題になることはまずないと思います。