乱数を生成するにはどうすればよいですか?

2010年04月25日に質問されました。  ·  閲覧回数 2.4M回  ·  ソース

Rella picture
2010年04月25日

C#でランダムな整数を生成するにはどうすればよいですか?

回答

Guffa picture
2010年04月25日
2603

Randomクラスは、乱数を作成するために使用されます。 (もちろん、疑似ランダムです。)

例:

Random rnd = new Random();
int month  = rnd.Next(1, 13);  // creates a number between 1 and 12
int dice   = rnd.Next(1, 7);   // creates a number between 1 and 6
int card   = rnd.Next(52);     // creates a number between 0 and 51

複数の乱数を作成する場合は、 Randomインスタンスを保持して再利用する必要があります。 時間的に近すぎる新しいインスタンスを作成すると、ランダムジェネレーターがシステムクロックからシードされるのと同じ一連の乱数が生成されます。

Shivprasad Koirala picture
2016年06月14日
307

質問は非常に単純に見えますが、答えは少し複雑です。 ほぼ全員がRandomクラスの使用を提案しており、一部の人はRNG暗号クラスの使用を提案しています。 しかし、いつ何を選択するか。

そのためには、最初にランダムという用語とその背後にある哲学を理解する必要があります。

C# https://www.youtube.com/watch?v = tCYxc-2-3fYを使用して、ランダムネスの哲学を深く掘り下げたこのビデオを

まず、ランダムネスの哲学を理解しましょう。 人に赤、緑、黄色のいずれかを選択するように指示すると、内部で何が起こるかがわかります。 人が赤、黄、緑を選ぶ理由は何ですか?

c# Random

彼の選択を決定する人の心にいくつかの最初の考えが入ります、それは好きな色、幸運な色などである可能性があります。 言い換えると、RANDOMでSEEDと呼ぶ初期トリガーです。このSEEDは開始点であり、RANDOM値を選択するように促します。

今、SEEDは、ランダムな数字とは種類がPSEUDOとするとき、シードは、それらの乱数を推測することは困難であると呼ばれている推測しやすい場合SECURED乱数と呼ばれています。

たとえば、天気と音の組み合わせに応じて色を選択すると、最初の種を推測するのは困難になります。

c# Random

ここで重要な声明を述べさせてください:-

*「Random」クラスはPSEUDO乱数のみを生成し、SECURE乱数を生成するには、「RNGCryptoServiceProvider」クラスを使用する必要があります。

c# Random

ランダムクラスは、非常に予測可能なCPUクロックからシード値を取得します。 つまり、C#のRANDOMクラスは疑似乱数を生成します。以下はそのコードです。

var random = new Random();
int randomnumber = random.Next()

RNGCryptoServiceProviderクラスは、OSエントロピーを使用してシードを生成します。 OSエントロピーは、サウンド、マウスクリック、キーボードタイミング、熱温度などを使用して生成されるランダムな値です。以下に同じコードを示します。

using (RNGCryptoServiceProvider rg = new RNGCryptoServiceProvider()) 
{ 
    byte[] rno = new byte[5];    
    rg.GetBytes(rno);    
    int randomvalue = BitConverter.ToInt32(rno, 0); 
}

OSエントロピーを理解するには、14 30https 2-3fYのこのビデオを参照してください。OSエントロピーのロジックが説明されています。 したがって、簡単な言葉で言えば、RNGCryptoは安全な乱数を生成します。

Pankaj Mishra picture
2010年10月04日
239

新しいRandom()を実行するたびに、初期化されます。 これは、タイトなループでは、同じ値を何度も取得することを意味します。 単一のランダムインスタンスを保持し、同じインスタンスでNextを使用し続ける必要があります。

//Function to get random number
private static readonly Random getrandom = new Random();

public static int GetRandomNumber(int min, int max)
{
    lock(getrandom) // synchronize
    {
        return getrandom.Next(min, max);
    }
}
Fyodor Soikin picture
2010年04月25日
96

new Random()は現在のタイムスタンプにシードされていることに注意してください。

1つの番号だけを生成する場合は、次を使用できます。

new Random().Next( int.MinValue, int.MaxValue )

詳細については、ランダムクラスを参照してください。ただし、次の点に注意してください。

ただし、クロックの解像度は有限であるため、パラメーターなしのコンストラクターを使用して異なるRandomオブジェクトを連続して作成すると、同一の乱数シーケンスを生成する乱数ジェネレーターが作成されます。

したがって、このコードを使用して一連の乱数を生成しないでください。

Joren picture
2010年04月25日
53
Random r = new Random();
int n = r.Next();
joordan831 picture
2015年12月19日
32

暗号的に安全なバージョンを追加したかった:

RNGCryptoServiceProviderクラス( MSDNまたはdotnetperls

IDisposableを実装します。

using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
   byte[] randomNumber = new byte[4];//4 for int32
   rng.GetBytes(randomNumber);
   int value = BitConverter.ToInt32(randomNumber, 0);
}
mbcrump picture
2010年04月25日
16

Jon SkeetのStaticRandomメソッドは、彼が疑似乱数用に作成したMiscUtilクラスライブラリ内で使用できます。

using MiscUtil;
...

for (int i = 0; i < 100; 
    Console.WriteLine(StaticRandom.Next());
Proximo picture
2015年05月20日
14

COBOLの回答を除いて、これらすべてのソリューションを試しました...笑

これらの解決策はどれも十分ではありませんでした。 高速forintループでランダムが必要であり、非常に広い範囲でも大量の重複値を取得していました。 あまりにも長い間ランダムな結果に落ち着いた後、私はついにこの問題に一度だけ取り組むことにしました。

それはすべて種子についてです。

Guidから非数字を解析してランダムな整数を作成し、それを使用してRandomクラスをインスタンス化します。

public int GenerateRandom(int min, int max)
{
    var seed = Convert.ToInt32(Regex.Match(Guid.NewGuid().ToString(), @"\d+").Value);
    return new Random(seed).Next(min, max);
}

更新:Randomクラスを一度インスタンス化する場合、シードは必要ありません。 したがって、静的クラスを作成し、それからメソッドを呼び出すのが最善です。

public static class IntUtil
{
   private static Random random;

   private static void Init()
   {
      if (random == null) random = new Random();
   }

   public static int Random(int min, int max)
   {
      Init();
      return random.Next(min, max);
   }
}

次に、そのように静的クラスを使用できます。

for(var i = 0; i < 1000; i++)
{
   int randomNumber = IntUtil.Random(1,100);
   Console.WriteLine(randomNumber); 
}

私はこのアプローチの方が好きだと認めます。

Mohamed Selim picture
2015年11月01日
13

ランダムオブジェクトを作成する

Random rand = new Random();

そしてそれを使用します

int randomNumber = rand.Next(min, max);

乱数が必要になるたびにnew Random()を初期化する必要はありません。ランダムを開始し、ループ内などで必要な回数だけ使用します。

Anshita Arya picture
2015年07月22日
11

組み込みのRandomクラス(System.Random)によって生成された数値は、疑似乱数を生成します。

真の乱数が必要な場合、取得できる最も近いものは、 RNGCryptoServiceProviderなどのC#の暗号化クラスを使用して生成できる「安全な疑似乱数ジェネレーター」です。

それでも、真の乱数が必要な場合は、放射性崩壊を説明するデバイスなどの外部ソースを乱数ジェネレーターのシードとして使用する必要があります。 定義上、純粋にアルゴリズム的な手段によって生成された数値は、真にランダムにはなり得ないためです。