如何使用C#中的Random
类生成随机的Int64和UInt64值?
这应该能解决问题。(这是一个扩展方法,因此您可以像调用Random
对象上的普通Next
或NextDouble
方法一样调用它)。
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
类,当随机性(通常量化为information entropy)不是问题时,这是首选解决方案。出于兴趣,请参阅其他答案,其中提到了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()
,移动一个值,然后进行OR/添加操作是行不通的。Random.Next()
只生成非负整数,即它生成31位而不是32位,因此两次调用的结果仅产生62个随机位,而不是覆盖完整范围的64位Int64
/UInt64
所需的64位。( Guffa的答案展示了如何使用三个调用Random.Next()
来实现。)Z = X0 + X1*256 + X2*256*256 + ...
,其中独立随机生成的X0
、X1
... X7
,因此在一般情况下,Z
不会是均匀分布变量。Z
可以是范围内的任何值,但并非所有值具有相等概率。 - Alex ZhukovskiyZ = X0 + X1*256 + X2*256*256 + ...
在这里有点不正确。最后,我们可以通过仅指定底部边界 int.MaxValue
,使用 4(或 3 个正值) rand.Next()
调用生成一个值。这比 8 次调用更好(因为 Random.NextBytes
对每个字节调用 InternalSample
)。 - Alex ZhukovskiyRandom.Next
来实现,因为每次调用会生成31位的随机数据,而我们只需要总共64位。 - Jon Skeet这里是代码,使用的是加密服务(而不是Random
类),理论上比Random类更好的随机数生成器。你可以很容易地将其作为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返回的值不是“密码学安全”的,不应该用于涉及(大量的)秘密或(大量的)金钱的事情。
另一个使用 RNGCryptoServiceProvider
而不是 Random
的答案。在这里,您可以看到如何移除 MSB,使结果始终为正。
public static Int64 NextInt64()
{
var buffer = new byte[8];
new RNGCryptoServiceProvider().GetBytes(buffer);
return BitConverter.ToInt64(buffer, 0) & 0x7FFFFFFFFFFFFFFF;
}
Random
类有一个生成随机长整型的方法。var r = new Random();
long randomLong = r.NextInt64();
Random r=new Random();
int j=r.next(1,23);
Console.WriteLine(j);