簡體   English   中英

在 C# 中生成隨機值

[英]Generate random values in C#

如何使用 C# 中的Random class 生成隨機 Int64 和 UInt64 值?

這應該可以解決問題。 (它是一種擴展方法,因此您可以像在Random對象上調用普通的NextNextDouble方法一樣調用它)。

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

如果你想要無符號整數,只需在任何地方用UInt64替換Int64 ,一切都應該正常工作。

注意:由於沒有提供關於生成數字的安全性或所需隨機性的上下文(實際上 OP 特別提到了Random類),我的示例僅處理Random class,這是隨機性時的首選解決方案(通常量化為信息熵)不是問題。 有趣的是,請參閱其他提到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()兩次,移動一個值然后 ORing/adding 不起作用。 Random.Next()只產生非負整數,即它產生 31 位,而不是 32 位,因此兩次調用的結果只產生 62 位隨機位,而不是覆蓋Int64 / UInt64的完整范圍所需的 64 位。 Guffa 的回答顯示了如何通過對Random.Next()三個調用來做到這一點。)

這里是 go,它使用了crytpo 服務(不是Random類) ,它(理論上)是比 Random class 更好的 RNG。 您可以輕松地將其作為 Random 的擴展或制作您自己的 Random class,其中 RNGCryptoServiceProvider 是類級別的 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);        
}

您可以使用位移將 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;
}

截至.NET 6, Random class有生成隨機long的方法。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM