在 C# 中生成随机值

发布于 2024-07-16 03:55:38 字数 61 浏览 7 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

无言温柔 2024-07-23 03:55:39

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

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类),我的示例仅处理< code>Random 类,这是随机性时的首选解决方案(通常量化为信息熵) 不是问题。 感兴趣的是,请参阅提到 RNGCryptoServiceProviderSystem.Security 命名空间中提供的 RNG)的其他答案,它的使用几乎相同。

This should do the trick. (It's an extension method so that you can call it just as you call the normal Next or NextDouble methods on a Random object).

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

Just replace Int64 with UInt64 everywhere if you want unsigned integers instead and all should work fine.

Note: Since no context was provided regarding security or the desired randomness of the generated numbers (in fact the OP specifically mentioned the Random class), my example simply deals with the Random class, 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.Security namespace), which can be used almost identically.

余生一个溪 2024-07-23 03:55:39

使用 Random.NextBytes()< /a> 和 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() 两次,移动一个值然后进行“或”/相加不起作用。 Random.Next() 仅生成非负整数,即生成 31 位,而不是 32 位,因此两次调用的结果仅生成 62 位随机位,而不是覆盖整个范围所需的 64 位Int64/UInt64。 (Guffa 的答案展示了如何使用三个< /em> 调用 Random.Next() 。)

Use Random.NextBytes() and 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 answer shows how to do it with three calls to Random.Next() though.)

烟花肆意 2024-07-23 03:55:39

在这里,它使用了加密货币服务(不是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);        
}

Here you go, this uses the crytpo services (not the Random class), 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.

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);        
}
深爱成瘾 2024-07-23 03:55:39

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

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

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:

long r = rnd.Next();
r <<= 31;
r |= rnd.Next();
r <<= 31;
r |= rnd.Next();
悍妇囚夫 2024-07-23 03:55:39

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

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 使用大气噪声来生成随机性,显然用于彩票等。

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.

玩套路吗 2024-07-23 03:55:39

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

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

祁梦 2024-07-23 03:55:39

您可以创建一个 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);

You could create a byte array, fill it with random data and then convert it to long (Int64) or 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);
北方的巷 2024-07-23 03:55:39

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

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

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

public static Int64 NextInt64()
{
    var buffer = new byte[8];
    new RNGCryptoServiceProvider().GetBytes(buffer);
    return BitConverter.ToInt64(buffer, 0) & 0x7FFFFFFFFFFFFFFF;
}
迷爱 2024-07-23 03:55:39

从 .NET 6 开始,Random 类具有生成随机 long 的方法。

var r = new Random();
long randomLong = r.NextInt64();

As of .NET 6, the Random class has a method for generating a random long.

var r = new Random();
long randomLong = r.NextInt64();
囚你心 2024-07-23 03:55:39
Random r=new Random();
int j=r.next(1,23);
Console.WriteLine(j);
Random r=new Random();
int j=r.next(1,23);
Console.WriteLine(j);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文