5

数値を入力として受け取り、別の数値を返す疑似乱数ジェネレータが必要です。ウィッチは再現可能で、ランダムのようです。

  • 各入力番号は正確に1つの出力番号と一致する必要があり、その逆も同様です。
  • 同じ入力番号は常に同じ出力番号になります
  • 互いに近い連続した入力番号(例:1と2)は、完全に異なる出力番号を生成する必要があります(例:1 => 9783526、2 => 283)

完璧であってはなりません。ランダムで再現性のあるテストデータを作成するだけです。

私はC#を使用しています。


私はこの面白いコードを少し前に書いたので、ランダムなものが生成されました。

  public static long Scramble(long number, long max) 
  {
    // some random values 
    long[] scramblers = { 3, 5, 7, 31, 343, 2348, 89897 };
    number += (max / 7) + 6;
    number %= max;
    // shuffle according to divisibility
    foreach (long scrambler in scramblers) 
    {
      if (scrambler >= max / 3) break;
      number = ((number * scrambler) % max) 
        + ((number * scrambler) / max);
    }

    return number % max;
  }

私は、より良い、より信頼性の高い、任意のサイズの数値(最大引数なし)で動作するものが欲しいです。

これはおそらくCRCアルゴリズムを使用して解決できますか?または、少しシャッフルするもの。

4

4 に答える 4

4

この回答からマイクロソフトのコードを削除します。GNU コード ファイルはかなり長くなりますが、基本的にはhttp://cs.uccs.edu/~cs591/bufferOverflow/glibc-2.2.4/stdlib/random_r.cからこれが含まれています。

int32_t val = state[0];
val = ((state[0] * 1103515245) + 12345) & 0x7fffffff;
state[0] = val;
*result = val;

あなたの目的のために、シードはstate [0]であるため、より似ています

int getRand(int val)
{
    return ((val * 1103515245) + 12345) & 0x7fffffff;
}
于 2009-10-08T13:59:00.903 に答える
3

Random クラスを使用して、C# でこれを簡単に行うことができます (おそらく)。

public int GetPseudoRandomNumber(int input)
{
    Random random = new Random(input);
    return random.Next();
}

ランダムに入力を明示的にシードしているため、同じ入力値が与えられるたびに同じ出力が得られます。

于 2009-10-08T13:54:24.453 に答える
2

tausworthe ジェネレーターは実装が簡単で、非常に高速です。次の疑似コードの実装には、完全なサイクルがあります (ゼロは固定小数点であるため、2**31 - 1)。

def tausworthe(seed)
  seed ^= seed >> 13
  seed ^= seed << 18
  return seed & 0x7fffffff

C# はわかりませんが、C のように XOR ( ^) とビット シフト ( <<, >>) 演算子があると思います。

初期シード値を設定し、 で呼び出しseed = tausworthe(seed)ます。

于 2014-05-26T17:42:25.533 に答える
1

最初の 2 つのルールは、入力の固定順列または入力シード順列を提案しますが、3 番目のルールはさらに変換を必要とします。

その変換を導くために、出力がどうあるべきかについてさらに制限はありますか? - たとえば、選択できる出力値の入力セットはありますか?

唯一のガイドが「最大なし」の場合、次を使用します...

  1. 入力全体にハッシュ アルゴリズムを適用して、最初の出力項目を取得します。CRC が機能する場合もありますが、より「ランダムな」結果を得るには、MD5 などの暗号ハッシュ アルゴリズムを使用します。

  2. 入力で次の順列アルゴリズム (Google の多数のリンク) を使用します。

  3. 必要な出力がすべて見つかるまで、hash-then-next-permutation を繰り返します。

ただし、次の順列はやり過ぎかもしれませんが、ハッシュをやり直す前に、おそらく最初の入力をインクリメントするだけで済みます (オーバーフローが発生した場合は、2 番目の入力をインクリメントするなど)。

暗号スタイルのハッシュには、キーが必要です。開始する前に、入力から何かを導出するだけです。

于 2009-10-08T14:39:19.993 に答える