ホームページ  >  に質問  >  本文

Javascript で乱数ジェネレーターをシードする

<p>JavaScript で乱数生成器 (<code>Math.random</code>) をシードすることは可能ですか? </p>
P粉006977956P粉006977956423日前597

全員に返信(2)返信します

  • P粉482108310

    P粉4821083102023-08-24 22:35:05

    いいえ、Math.random() を播種することはできません。 ECMAScript 仕様 は、この件に関して意図的に曖昧にしており、シード方法を提供していないか、ブラウザに同じアルゴリズムを使用することさえ要求しています。したがって、そのような機能は外部から提供する必要がありますが、幸いなことに、これはそれほど難しいことではありません。

    私は、純粋な JavaScript で、数多くの優れた、短くて高速な 擬似乱数ジェネレーター (PRNG) 関数を実装しました。これらはすべてシードすることができ、高品質の数値を提供します。これらはセキュリティ目的ではありません。シード可能な CSPRNG が必要な場合は、ISAAC をチェックしてください。

    まず、PRNG を正しく初期化するように注意してください。 簡単にするために、以下のジェネレーターにはシード生成プロセスが組み込まれていませんが、PRNG の初期 シード状態として 1 つ以上の 32 ビット数値を受け入れます。類似またはまばらなシード (例: 1 と 2 の単純なシード) はエントロピーが低く、相関またはその他のランダム性の品質の問題を引き起こす可能性があり、場合によっては同様の特性を持つ出力が発生します (例: ランダムに生成されたレベルが類似している)。これを回避するためのベスト プラクティスは、均一に分散された高エントロピー シードで PRNG を初期化するか、最初の 15 程度の数を超えて進めることです。

    これを行うには多くの方法がありますが、ここでは 2 つの方法を紹介します。まず、ハッシュ関数は、短い文字列からシードを生成するのに非常に優れています。 2 つの文字列が類似している場合でも、優れたハッシュ関数はまったく異なる結果を生成するため、文字列についてあまり深く考える必要はありません。ハッシュ関数の例を次に示します:

    リーリー

    cyrb128 を呼び出すと、PRNG のシードに使用できる文字列から 128 ビットのハッシュ値が生成されます。使用方法は次のとおりです:

    リーリー

    注: もう少し強力な 128 ビット ハッシュが必要な場合は、MurmurHash3_x86_128 を検討してください。これはより完全ですが、大規模な配列での使用を目的としています。

    または、シードを設定するダミー データを選択し、事前にジェネレーターを数回 (12 ~ 20 回の反復) 進めて、初期状態を完全に混合します。これには単純であるという利点があり、PRNG のリファレンス実装でよく使用されますが、初期状態の数が制限されます。 リーリー

    注: これらの PRNG 関数の出力は、正の 32 ビット数値 (0 ~ 2

    32-1) を生成し、その後 0 ~ 1 (0 を含む) の浮動小数点数に変換されます。 , 1) は Math.random() と同等です。特定の範囲の乱数が必要な場合は、MDN のこの記事をお読みください。元のビットだけが必要な場合は、最後の除算演算を削除するだけです。

    JavaScript 数値は、最大 53 ビット解像度の整数のみを表現できます。ビット単位の演算が使用される場合、この値は 32 に減ります。他の言語の最新の PRNG は 64 ビット操作を使用することが多いため、JS に移植するときに shim が必要となり、

    大幅にパフォーマンスが低下します。ここでのアルゴリズムは、JS と直接互換性があるため、32 ビット演算のみを使用します。


    sfc32 (シンプルな高速カウンタ)

    sfc32 は、PractRand 乱数テスト スイート (もちろん合格します) の一部です。 sfc32 は 128 ビット状態であり、JS では非常に高速です。

    リーリー

    #| とは何なのか疑問に思われるかもしれません。 0 および #>>>>= 0 が使用されます。これらは基本的に、パフォーマンスの最適化に使用される 32 ビット整数変換です。 JS の Number は基本的に浮動小数点数ですが、ビット単位の演算を行う場合は 32 ビット整数モードに切り替わります。このモードは JS インタープリターにより高速に処理されますが、乗算や加算を行うと浮動小数点に戻り、パフォーマンスが低下します。 桑32

    Mulberry32 は 32 ビット状態のシンプルなジェネレーターですが、非常に高速でランダム性が優れています (作者は、完全な 2

    32

    サイクルで gjrand テスト スイートに合格すると述べています。しかし、私はまだそれを確認していません)。 リーリー シンプルだが

    まともな

    PRNG が必要で、数十億の乱数が必要ない場合は、これをお勧めします (誕生日の質問 を参照)。 xoshiro128**

    2018 年 5 月現在、

    xoshiro128**

    は、Vigna と Blackman によって開発された Xorshift ファミリ の新しいメンバーです (Vigna 教授は Math.random の責任者でもあります##) # 実装はサポートを提供します)。これは、128 ビット状態を提供する最速のジェネレーターです。 リーリー 作者は、(警告にもかかわらず)ランダム性テストに十分合格すると主張しています。他の研究者は、TestU01 の一部のテスト (特に LinearComp と BinaryRank) に失敗したと指摘しました。実際には、浮動小数点数を扱う場合 (これらの実装など) に問題が発生することはありませんが、元の最下位ビットに依存している場合は問題が発生する可能性があります。

    JSF (ジェンキンスのリトルエクスプレス)

    これは、Bob Jenkins (2007) による最初の JSF または「smallprng」です。

    ゴースト ハッシュ

    PractRand テストに合格しており、sfc32 ほどではありませんが、かなり高速であるはずです。

    リーリー

    返事
    0
  • P粉596161915

    P粉5961619152023-08-24 09:59:41

    いいえ、Math.random() をシードすることはできませんが、独自のジェネレーターを作成するのは非常に簡単です。あるいは、既存のジェネレーターを使用することもできます。

    表示: この関連質問

    また、シーディングの詳細については、David Bau のブログを参照してください。

    返事
    0
  • キャンセル返事