如何使用Random
C# 中的类生成随机 Int64 和 UInt64 值?
9 回答
这应该可以解决问题。(它是一种扩展方法,因此您可以像调用对象上的普通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
(命名空间中提供的 RNG System.Security
),它们的使用几乎相同。
使用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()
。)
给你,这使用了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);
}
您可以使用位移将 31 位随机数组合成一个 64 位随机数,但您必须使用三个 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返回的值不是“加密安全的”,它们不应该用于涉及(大)秘密或(很多) 钱。
您可以创建一个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);
另一个答案,RNGCryptoServiceProvider
而不是Random
。在这里,您可以看到如何删除 MSB,因此结果始终为正。
public static Int64 NextInt64()
{
var buffer = new byte[8];
new RNGCryptoServiceProvider().GetBytes(buffer);
return BitConverter.ToInt64(buffer, 0) & 0x7FFFFFFFFFFFFFFF;
}
Random r=new Random();
int j=r.next(1,23);
Console.WriteLine(j);