33

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

4

9 回答 9

76

这应该可以解决问题。(它是一种扩展方法,因此您可以像调用对象上的普通NextNextDouble方法一样调用它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(命名空间中提供的 RNG System.Security),它们的使用几乎相同。

于 2009-03-24T13:27:41.593 回答
29

使用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()两次,移动一个值,然后 ORing/adding 不起作用。Random.Next()仅产生非负整数,即它产生 31 位,而不是 32,因此两次调用的结果仅产生 62 位随机位,而不是覆盖Int64/的完整范围所需的 64 位UInt64。(Guffa 的回答显示了如何通过三个调用来做到这一点Random.Next()。)

于 2009-03-24T13:26:19.570 回答
10

给你,这使用了crytpo 服务 (不是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);        
}
于 2009-03-24T14:41:23.397 回答
6

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

long r = rnd.Next();
r <<= 31;
r |= rnd.Next();
r <<= 31;
r |= rnd.Next();
于 2009-03-24T14:17:28.667 回答
5

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

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

于 2009-03-24T13:47:35.757 回答
3

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

于 2009-03-24T13:36:57.157 回答
2

您可以创建一个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);
于 2009-03-24T13:28:27.787 回答
0

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

public static Int64 NextInt64()
{
    var buffer = new byte[8];
    new RNGCryptoServiceProvider().GetBytes(buffer);
    return BitConverter.ToInt64(buffer, 0) & 0x7FFFFFFFFFFFFFFF;
}
于 2017-12-20T08:59:06.813 回答
-3
Random r=new Random();
int j=r.next(1,23);
Console.WriteLine(j);
于 2009-03-27T17:29:29.897 回答