Random 種子問題


1:隨機數生成器

Random 是 .NET 的偽隨機數生成器,要生成各種類型的隨機數,必須先得到它的實例對象,然后再生成隨機數

2:種子

隨機數的生成是從種子值開始。 如果反復使用同一個種子,就會生成相同的數字系列,產生不同序列的一種方法是使種子值與時間相關

3:對象實例

默認情況下,Random 類的無參數構造函數使用系統時鍾生成其種子值

參數化構造函數可提供一個 Int32 類型的數字為起始值

4:生成方案

方案1:只實例化一個對象,多次方法調用

Random rnd = new Random();
int i1 = rnd.Next(10);
int i2 = rnd.Next(10);
  
// 簡單,方便,常用,生成的數字分布均勻,每個數字返回的可能性均相等。
// 一般是實例為靜態對象,以減少實例化的次數,避免產生相同的種子值,如下:
private static RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider();

方案2:每次方法調用都用一個新的實例(無參)

Random rnd1 = new Random();
int i1 = rnd2.Next(10);
  
Random rnd2 = new Random();
int i2 = rnd2.Next(10);
  
// 兩個隨機數十有八九相同
// 默認種子值是從系統時鍾派生而來的,具有有限的分辨率。
// 因此,通過調用默認構造函數而頻繁創建的不同對象將具有相同的默認種子值,因而會產生幾組相同的隨機數。

解決方案:

阻塞當前線程一小段時間

Random rnd1 = new Random();
System.Threading.Thread.Sleep(500);
Random rnd2 = new Random();

或者:應用一個算法來區分每個調用的種子值。

例如,下面的代碼使用右移位運算符為多個可以使用相同時間值初始化的 Random 對象(在 1 和大約 28 個對象之間)生成不同的種子值。

int count = 4;
Random[] rnds = new Random[count];
  
for (int i = 0; i < count; i++)
{
    rnds[i] = new Random(unchecked((int)(DateTime.Now.Ticks >> i)));
}

5:通用數字和字母隨機生成方案

數組方式:略

字符串方式:不靈活,但比較簡便,用於驗證碼已足夠

string str = @"0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ";
  
public string GetMix(Random rnd)
{
    // 返回數字
    // return rnd.Next(10).ToString();
  
    // 返回小寫字母
    // return str.Substring(10+rnd.Next(26),1);
  
    // 返回大寫字母
    // return str.Substring(36+rnd.Next(26),1);
  
    // 返回大小寫字母混合
    // return str.Substring(10+rnd.Next(52),1);
  
    // 返回小寫字母和數字混合
    // return str.Substring(0 + rnd.Next(36), 1);
  
    // 返回大寫字母和數字混合
    // return str.Substring(0 + rnd.Next(36), 1).ToUpper();
  
    // 返回大小寫字母和數字混合
    return str.Substring(0 + rnd.Next(61), 1);
}

6:用隨機數填充指定字節的數組

Random rnd = new Random();
  
// 數組長度自定義 
byte[] bs = new byte[9999];
  
// 字節數組的每個元素均設置為一個大於等於零而小於或等於 MaxValue 的隨機數。MaxValue=255,可取上界值 
rnd.NextBytes(bs);

7:生成大於等於 0.0 小於 1.0 的雙精度浮點數

Random rnd = new Random();
  
// 大於等於 0.0 並且小於 1.0 的雙精度浮點數。 
double d = rnd.NextDouble();
  
// 格式化為 5 位小數,當然還有更多種格式化 
string s = string.Format("{0:F5}", d);

8:生成隨機整數

Random rnd = new Random();
  
// 大於等於零且小於 MaxValue 的 32 位帶符號整數。MaxValue=2,147,483,647,不可取上界值 
int i1 = rnd.Next();
  
// 大於等於零且小於 maxValue 的 32 位帶符號整數,不可取上界值 
int i2 = rnd.Next(10);
  
// 一個大於等於 minValue 且小於 maxValue 的 32 位帶符號整數,不可取上界值,可以取負值 
int i3 = rnd.Next(-10, 100);

9:生成隨機大寫字母

public string GetUpperCase(Random rnd)
{
    // A-Z  ASCII值  65-90 
    int i = rnd.Next(65, 91);
    char c = (char)i;
    return c.ToString();
}

 10:生成隨機小寫字母

public string GetLowerCase(Random rnd)
{
    // a-z  ASCII值  97-122 
    int i = rnd.Next(97, 123);
    char c = (char)i;
    return c.ToString();
}

11:生成隨機大小寫字母混合

public string GetLetter(Random rnd)
{
    // A-Z  ASCII值  65-90
    // a-z  ASCII值  97-122
    int i = rnd.Next(65, 123);
    char c = (char)i;
    if (char.IsLetter(c))
    {
        return c.ToString();
    }
    else
    {
        // 遞歸調用,直到隨機到字母
        return GetLetter(rnd);
    }
}

12:生成隨機大小寫字母和數字混合

public string GetChar(Random rnd)
{
    // 0-9
    // A-Z  ASCII值  65-90
    // a-z  ASCII值  97-122
    int i = rnd.Next(0, 123);
    if (i < 10)
    {
        // 返回數字
        return i.ToString();
    }
  
    char c = (char)i;
  
    // 返回小寫字母加數字
    // return char.IsLower(c) ? c.ToString() : GetChar(rnd);
  
    // 返回大寫字母加數字
    // return char.IsUpper(c) ? c.ToString() : GetChar(rnd);
  
    // 返回大小寫字母加數字
    return char.IsLower(c) ? c.ToString() : GetChar(rnd);

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM