C#のRandom
クラスを使用してランダムなInt64値とUInt64値を生成するにはどうすればよいですか?
これでうまくいくはずです。 (これは拡張メソッドであるため、Next
オブジェクトで通常のNextDouble
またはRandom
メソッドを呼び出すのと同じように呼び出すことができます)。
public static Int64 NextInt64(this Random rnd)
{
var buffer = new byte[sizeof(Int64)];
rnd.NextBytes(buffer);
return BitConverter.ToInt64(buffer, 0);
}
代わりに符号なし整数が必要な場合は、どこでもInt64
をUInt64
に置き換えるだけで、すべて正常に機能するはずです。
注:セキュリティまたは生成された数値の望ましいランダム性に関するコンテキストが提供されなかったため(実際、OPはRandom
クラスについて具体的に言及しました)、私の例は単にRandom
クラスを扱っています。これは、ランダム性( 情報エントロピー として定量化されることが多い)が問題にならない場合に推奨されるソリューションです。興味深いことに、RNGCryptoServiceProvider
(System.Security
名前空間で提供されるRNG)に言及している他の回答を参照してください。これは、ほぼ同じように使用できます。
Random.NextBytes()
および BitConverter.ToInt64
/ BitConverter.ToUInt64
を使用します。
// Assume rng refers to an instance of System.Random
byte[] bytes = new byte[8];
rng.NextBytes(bytes);
long int64 = BitConverter.ToInt64(bytes, 0);
ulong uint64 = BitConverter.ToUInt64(bytes, 0);
Random.Next()
を2回使用し、1つの値をシフトしてから、ORing/addingが機能しないことに注意してください。 Random.Next()
は非負の整数のみを生成します。つまり、32ではなく31ビットを生成するため、2回の呼び出しの結果は、Int64
/UInt64
の全範囲をカバーするために必要な64ビットではなく、62のランダムビットのみを生成します。 ( Guffaの答え はRandom.Next()
への3つの呼び出しでそれを行う方法を示しています。)
ここでは、これはcrytpo services(Randomクラスではありません)を使用します。これは(理論的には)より優れたRNGです。ランダムクラス。これをRandomの拡張にすることも、RNGCryptoServiceProviderがクラスレベルのオブジェクトである独自のRandomクラスを作成することも簡単にできます。
using System.Security.Cryptography;
public static Int64 NextInt64()
{
var bytes = new byte[sizeof(Int64)];
RNGCryptoServiceProvider Gen = new RNGCryptoServiceProvider();
Gen.GetBytes(bytes);
return BitConverter.ToInt64(bytes , 0);
}
ビットシフトを使用して、31ビットの乱数から64ビットの乱数を組み合わせることができますが、十分なビットを取得するには、3つの31ビットの数値を使用する必要があります。
long r = rnd.Next();
r <<= 31;
r |= rnd.Next();
r <<= 31;
r |= rnd.Next();
私は常にこれを使用してランダムシードを取得します(簡潔にするためにエラーチェックを削除しました):
m_randomURL = "https://www.random.org/cgi-bin/randnum?num=1&min=1&max=1000000000";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(m_randomURL);
StreamReader stIn = new StreamReader(req.GetResponse().GetResponseStream());
Random Rand = new Random(Convert.ToInt32(stIn.ReadToEnd()));
random.orgは、大気ノイズを使用してランダム性を生成し、宝くじなどに使用されているようです。
これらの乱数をどのように使用するかは言いません...Randomによって返される値は「暗号的に安全」ではなく、(を含むものには使用しないでください。大きな)秘密または(たくさんの)お金。
RNGCryptoServiceProvider
の代わりにRandom
を使用した別の回答。ここでは、結果が常にポジティブになるようにMSBを削除する方法を確認できます。
public static Int64 NextInt64()
{
var buffer = new byte[8];
new RNGCryptoServiceProvider().GetBytes(buffer);
return BitConverter.ToInt64(buffer, 0) & 0x7FFFFFFFFFFFFFFF;
}