在 C# 中生成随机值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/677373/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 13:04:43  来源:igfitidea点击:

Generate random values in C#

c#randomlong-integerint64

提问by SyncMaster

How can I generate random Int64 and UInt64 values using the Randomclass in C#?

如何使用RandomC# 中的类生成随机 Int64 和 UInt64 值?

采纳答案by Noldorin

This should do the trick. (It's an extension method so that you can call it just as you call the normal Nextor NextDoublemethods on a Randomobject).

这应该可以解决问题。(这是一个扩展方法,因此您可以像在对象上调用普通方法NextNextDouble方法一样调用它Random)。

public static Int64 NextInt64(this Random rnd)
{
    var buffer = new byte[sizeof(Int64)];
    rnd.NextBytes(buffer);
    return BitConverter.ToInt64(buffer, 0);
}

Just replace Int64with UInt64everywhere if you want unsigned integers instead and all should work fine.

如果您想要无符号整数,只需替换Int64UInt64无处不在,一切都应该可以正常工作。

Note:Since no context was provided regarding security or the desired randomness of the generated numbers (in fact the OP specifically mentioned the Randomclass), my example simply deals with the Randomclass, which is the preferred solution when randomness (often quantified as information entropy) is not an issue. As a matter of interest, see the other answers that mention RNGCryptoServiceProvider(the RNG provided in the System.Securitynamespace), which can be used almost identically.

注意:由于没有提供有关生成数字的安全性或所需随机性的上下文(实际上 OP 专门提到了Random该类),我的示例仅涉及Random该类,这是随机性时的首选解决方案(通常量化为信息熵)不是问题。有趣的是,请参阅提到的其他答案RNGCryptoServiceProviderSystem.Security命名空间中提供的 RNG ),它们几乎可以相同地使用。

回答by Jon Skeet

Use Random.NextBytes()and BitConverter.ToInt64/ BitConverter.ToUInt64.

使用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);

Note that using Random.Next()twice, shifting one value and then ORing/adding doesn't work. Random.Next()only produces non-negative integers, i.e. it generates 31 bits, not 32, so the result of two calls only produces 62 random bits instead of the 64 bits required to cover the complete range of Int64/UInt64. (Guffa's answershows how to do it with threecalls to Random.Next()though.)

请注意,使用Random.Next()两次,移动一个值,然后 ORing/adding 不起作用。Random.Next()只产生非负整数,即它产生 31 位,而不是 32,所以两次调用的结果只产生 62 个随机位,而不是覆盖Int64/的完整范围所需的 64 位UInt64。(古法的回答显示了如何通过三个调用来做到这一点Random.Next()。)

回答by Samuel

You could create a bytearray, fill it with random data and then convert it to long(Int64) or ulong(UInt64).

您可以创建一个byte数组,用随机数据填充它,然后将其转换为long( Int64) 或ulong( UInt64)。

byte[] buffer = new byte[sizeof(Int64)];
Random random = new Random();

random.NextBytes(buffer);
long signed = BitConverter.ToInt64(buffer, 0);

random.NextBytes(buffer);
long unsigned = BitConverter.ToUInt64(buffer, 0);

回答by Dаn

You don't say how you're going to use these random numbers...keep in mind that values returned by Randomare not "cryptographically secure" and they shouldn't be used for things involving (big) secrets or (lots of) money.

你没有说你将如何使用这些随机数......请记住,Random返回的值不是“密码安全的”,它们不应该用于涉及(大)秘密或(大量) ) 钱。

回答by sipwiz

I always use this to get my random seed (error checking removed for brevity):

我总是用它来获取我的随机种子(为简洁起见,已删除错误检查):

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 uses atmospheric noise to generate the randomness and is apparently used for lotteries and such.

random.org 使用大气噪声来生成随机性,显然用于彩票等。

回答by Guffa

You can use bit shift to put together a 64 bit random number from 31 bit random numbers, but you have to use three 31 bit numbers to get enough bits:

您可以使用位移将 31 位随机数组合成一个 64 位随机数,但您必须使用三个 31 位数字才能获得足够的位:

long r = rnd.Next();
r <<= 31;
r |= rnd.Next();
r <<= 31;
r |= rnd.Next();

回答by Muad'Dib

Here you go, this uses the crytpo services(not the Randomclass), which is (theoretically) a better RNG then the Random class. You could easily make this an extension of Random or make your own Random class where the RNGCryptoServiceProvider is a class-level object.

在这里,这使用了密码服务(不是Random类),它(理论上)是比 Random 类更好的 RNG。您可以轻松地将其作为 Random 的扩展或创建您自己的 Random 类,其中 RNGCryptoServiceProvider 是一个类级对象。

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);        
}

回答by Muad'Dib

Random r=new Random();
int j=r.next(1,23);
Console.WriteLine(j);

回答by sventevit

Another answer with RNGCryptoServiceProviderinstead of Random. Here you can see how to remove the MSB so the result is always positive.

使用RNGCryptoServiceProvider而不是的另一个答案Random。在这里您可以看到如何删除 MSB,以便结果始终为正。

public static Int64 NextInt64()
{
    var buffer = new byte[8];
    new RNGCryptoServiceProvider().GetBytes(buffer);
    return BitConverter.ToInt64(buffer, 0) & 0x7FFFFFFFFFFFFFFF;
}