Random\Engine::generate

ランダムな値を生成する

説明

public string Random\Engine::generate()

ランダムな値を生成し、アルゴリズムの内部的なステートをひとつ進めます。

ランダムな値は、ランダムなバイト列を含んだバイナリ文字列として表現されます。 そう表現することで、アルゴリズムが生成したランダムなビットを、 曖昧さがない形で解釈できるようになります。 これはたとえば、アルゴリズムによって異なる出力サイズを調整する目的があります。

整数の値をネイティブで操作するアルゴリズムは、 たとえば pack 関数に P フォーマットコードを指定するなどして、リトルエンディアンで整数値を返すべきです。 Random\Randomizer が提供する高レベルインターフェイスは、 数値表現が必要な場合、返されたランダムなバイト列を符号なしのリトルエンディアンとして解釈します。

返された文字列の個々のビットは、 等確率に、かつ独立に選ばれた状態にあることを強く推奨します。 アプリケーションによっては、正しく動作する要件が、 ビットレベルでランダムであることに依存する場合があるからです。 たとえば 線形合同法(LCGs) は、整数の下位ビットについては品質が低いランダムな値を生成するため、 ビットレベルでランダムな状態を必須とするアプリケーションには適していません。

パラメータ

この関数にはパラメータはありません。

戻り値

ランダムなバイト列を含む、空でない文字列を返します。

注意: Random\Randomizer は内部的に、符号なしの64ビット整数を使って動作します。 返される文字列が 64ビット(8バイト)以上のランダムな文字列である場合、 64ビットを超えるバイト列は無視されます。 他のアプリケーションでは、 64ビット以上のデータを一度に処理できるものがあるかもしれません。

エラー / 例外

  • ランダムな値を生成できなかった場合、 Random\RandomException がスローされます。 値を生成している途中でスローされる他の Exception は、 キャッチされて Random\RandomException でラップされます。
  • 返される文字列が空の場合、 Random\RandomizerRandom\BrokenRandomEngineError をスローします。
  • 実装されているアルゴリズムにとても強い偏りがある場合、 Random\RandomizerRandom\BrokenRandomEngineError をスローする場合があります。 これは、偏りがない結果を返すために棄却サンプリングが必要な時に、 無限ループに陥ることを避けるためです。

例1 Random\Engine::generate の例

<?php
/**
 * 65536 を法とする LCG(Linear Congruential Generator, 線形合同法)を実装し、
 * 61 を掛けて 17 を足し、8ビットの整数を返します。
 *
 * 注意: このエンジンはデモの用途のみに適した実装です。
 *       LCG は一般的に、低い品質のランダムな値しか生成しませんし、
 *       ここで示す実装は、16ビットというとても短い周期しか持っていません。
 *       これは、殆どの現実の需要を満たしません。
 */
final class LinearCongruentialGenerator implements \Random\Engine
{
    private int $state;

    public function __construct(?int $seed = null)
    {
        if ($seed === null) {
            $seed = random_int(0, 0xffff);
        }

        $this->state = $seed & 0xffff;
    }

    public function generate(): string
    {
        $this->state = (61 * $this->state + 17) & 0xffff;

        return pack('C', $this->state >> 8);
    }
}

$r = new \Random\Randomizer(
    new LinearCongruentialGenerator(seed: 1)
);

echo "Lucky Number: ", $r->getInt(0, 99), "\n";
?>

上の例の出力は以下となります。

Lucky Number: 4