Làm thế nào để tôi tạo một số int ngẫu nhiên?


1922

Làm cách nào để tạo một số nguyên ngẫu nhiên trong C #?

Câu trả lời:


2503

Các Randomlớp học được sử dụng để tạo ra số ngẫu nhiên. (Giả ngẫu nhiên đó là tất nhiên.).

Thí dụ:

Random rnd = new Random();
int month  = rnd.Next(1, 13);  // creates a number between 1 and 12
int dice   = rnd.Next(1, 7);   // creates a number between 1 and 6
int card   = rnd.Next(52);     // creates a number between 0 and 51

Nếu bạn định tạo nhiều hơn một số ngẫu nhiên, bạn nên giữ lại Randomthể hiện và sử dụng lại nó. Nếu bạn tạo các thể hiện mới quá gần với thời gian, chúng sẽ tạo ra một chuỗi các số ngẫu nhiên giống như trình tạo ngẫu nhiên được gieo từ đồng hồ hệ thống.


184
Chỉ cần một lưu ý cho người dùng Unity C #, bạn phải chỉ định "System.Random ()" vì Unity có "UnityEngine.Random ()", xung đột (lưu ý rằng "UnityEngine.Random ()" không có khả năng tạo ngẫu nhiên số). Vì sự thống nhất không phải lúc nào cũng nhập Hệ thống theo mặc định, điều này có thể gây ra một số nhầm lẫn.
Joehot200

2
Để sử dụng lại, bạn có thể khai báo rndstaticvà / hoặc đặt nó chỉ một lần khi khởi tạo mã.
Junior Mayhé

4
@JuniorM: Có, bạn có thể thực hiện tĩnh để sử dụng lại nó, nhưng bạn phải cẩn thận để không truy cập nó từ nhiều luồng vì nó không an toàn cho luồng (như thường lệ đối với bất kỳ lớp nào không được tạo luồng an toàn cụ thể ).
Guffa

9
Tôi nghĩ sẽ hữu ích khi thêm từ chối trách nhiệm rằng điều này không an toàn về mặt mật mã, vì đây là một câu hỏi phổ biến, chỉ trong trường hợp ai đó cố gắng làm mật mã với Random...
Daniel García Rubio

1
Câu trả lời tuyệt vời. Có một số "cải tiến" tốt Randomngoài kia để làm cho tính ngẫu nhiên của bạn mạnh mẽ hơn: ericlippert.com/2019/02/04/fixing-random-part-2codeblog.jonskeet.uk/2009/11/04/revisiting tính đồng nhất .
Jesse C. Choper

280

Câu hỏi có vẻ rất đơn giản nhưng câu trả lời hơi phức tạp. Nếu bạn thấy hầu hết mọi người đều đề nghị sử dụng lớp Ngẫu nhiên và một số người đã đề xuất sử dụng lớp tiền điện tử RNG. Nhưng khi nào thì chọn cái gì.

Vì vậy, trước tiên chúng ta cần hiểu thuật ngữ RANDOMNESS và triết lý đằng sau nó.

Tôi sẽ khuyến khích bạn xem video này đi sâu vào triết lý của RANDOMNESS bằng C # https://www.youtube.com/watch?v=tCYxc-2-3fY

Điều đầu tiên cho chúng tôi hiểu triết lý của RANDOMNESS. Khi chúng tôi nói với một người để lựa chọn giữa ĐỎ, XANH và VÀNG những gì xảy ra trong nội bộ. Điều gì khiến một người chọn ĐỎ hoặc VÀNG hoặc XANH?

c # Ngẫu nhiên

Một số suy nghĩ ban đầu đi vào tâm trí người quyết định lựa chọn của mình, đó có thể là màu sắc yêu thích, màu may mắn và vân vân. Nói cách khác, một số kích hoạt ban đầu mà chúng tôi gọi là RANDOM là SEED. SEED này là điểm bắt đầu, kích hoạt kích thích anh ta chọn giá trị RANDOM.

Bây giờ nếu một SEED dễ đoán thì những loại số ngẫu nhiên đó được gọi là PSEUDO và khi một hạt giống khó đoán những số ngẫu nhiên đó được gọi là số ngẫu nhiên được BẢO MẬT .

Ví dụ, một người chọn màu sắc tùy thuộc vào thời tiết và sự kết hợp âm thanh thì sẽ rất khó đoán hạt giống ban đầu.

c # Ngẫu nhiên

Bây giờ hãy để tôi đưa ra một tuyên bố quan trọng: -

* Lớp Random Random chỉ tạo số ngẫu nhiên PSEUDO và để tạo số ngẫu nhiên AN TOÀN, chúng ta cần sử dụng lớp RNGCryptoServiceProvider.

c # Ngẫu nhiên

Lớp ngẫu nhiên lấy các giá trị hạt giống từ đồng hồ CPU của bạn, điều này rất dễ đoán. Vì vậy, nói cách khác, lớp RANDOM của C # tạo ra các số ngẫu nhiên giả, bên dưới là mã cho cùng.

** Lưu ý: ** .NET Core 2.0.0+sử dụng một hạt giống khác trên hàm tạo không tham số: thay vì xung nhịp CPU mà nó sử dụng Guid.NewGuid().GetHashCode().

var random = new Random();
int randomnumber = random.Next()

Trong khi RNGCryptoServiceProviderlớp sử dụng entropy OS để tạo hạt giống. Entropy của hệ điều hành là một giá trị ngẫu nhiên được tạo bằng âm thanh, nhấp chuột và thời gian bàn phím, nhiệt độ, vv Dưới đây là mã cho cùng.

using (RNGCryptoServiceProvider rg = new RNGCryptoServiceProvider()) 
{ 
    byte[] rno = new byte[5];    
    rg.GetBytes(rno);    
    int randomvalue = BitConverter.ToInt32(rno, 0); 
}

Để hiểu entropy của hệ điều hành, hãy xem video này từ 14:30 https://www.youtube.com/watch?v=tCYxc-2-3fY nơi logic của entropy được giải thích. Vì vậy, đặt các từ đơn giản RNG Crypto tạo ra các số ngẫu nhiên AN TOÀN.


9
không nên là byte của bạn [5] chỉ [4] vì ToInt32 chỉ phân tích 4 byte?
Bernhard

6
Thật hữu ích khi biết những lớp học này sống ở đâu. System.Security.Cryptography
Elton

1
Bạn nên sử dụng RandomNumberGenerator.Create()thay vì gọi hàm tạo RNGCryptoServiceProvidervì nó không khả dụng trên tất cả các nền tảng.
dzitkowskik

Tôi chỉ muốn chính xác rằng SecureRandom là thế hệ ngẫu nhiên giả.
Nùménor

Do tính ngẫu nhiên tăng của hạt giống, tôi có thể tạo các đối tượng RNGCryptoServiceProvider mới mỗi khi tôi cần tạo một số ngẫu nhiên hay không, vẫn tốt hơn là tạo một đối tượng RNGCryptoServiceProvider và sử dụng lại bất cứ khi nào tôi cần tạo một số ngẫu nhiên, như Có nên thực hiện với lớp Random?
dùng2150989

231

Mỗi khi bạn thực hiện Random () mới, nó sẽ được khởi tạo. Điều này có nghĩa là trong một vòng lặp chặt chẽ, bạn nhận được cùng một giá trị rất nhiều lần. Bạn nên giữ một thể hiện ngẫu nhiên duy nhất và tiếp tục sử dụng Next trên cùng một thể hiện.

//Function to get random number
private static readonly Random getrandom = new Random();

public static int GetRandomNumber(int min, int max)
{
    lock(getrandom) // synchronize
    {
        return getrandom.Next(min, max);
    }
}

3
Đây có phải là những gì @Guffa đã nói trong câu trả lời của anh ấy 6 tháng trước không? "Nếu bạn tạo các trường hợp mới quá gần, họ sẽ tạo ra một chuỗi các số ngẫu nhiên giống nhau"
Chris

3
@ Chris- Đúng vậy những gì bạn nói. Trong này tôi đã cung cấp việc thực hiện đó. Tôi nghĩ rằng đó là một cách tốt để làm điều đó. Nó hoạt động tốt hơn.
Pankaj Mishra

22
Đây là một triển khai đồng bộ hóa mã để sử dụng từ các luồng thứ bảy. Điều đó tốt cho một ứng dụng đa luồng, nhưng lãng phí thời gian cho một ứng dụng luồng đơn.
Guffa

@SeanWorle: Đầu tiên, tôi đã thử nó với cách tiếp cận từ Guffa. Sau đó, tôi đã cố gắng để lưu trữ cùng một Randomđối tượng. Trong cả hai trường hợp, tôi nhận được cùng một số ngẫu nhiên. Với cách tiếp cận từ Pankaj, điều đó đã không xảy ra. Có lẽ điều này là ngẫu nhiên , nhưng tôi nghi ngờ nó bây giờ. Tôi đang truy vấn số ngẫu nhiên trong cùng một giây từ các luồng khác nhau.
thử nghiệm

1
@testing: Tôi đồng ý rằng phương pháp của Pankaj là phương pháp chính xác để sử dụng. Điều tôi đang nói là nó có thể được đơn giản hóa thành điều này: // Hàm để lấy số ngẫu nhiên riêng tư tĩnh chỉ đọc Random getrandom = new Random (); public static int GetRandomNumber (int min, int max) {lock (getrandom) {// đồng bộ hóa return getrandom.Next (min, max); }}
Sean Worle

92

Coi chừng đó new Random()là hạt giống trên dấu thời gian hiện tại.

Nếu bạn muốn tạo chỉ một số bạn có thể sử dụng:

new Random().Next( int.MinValue, int.MaxValue )

Để biết thêm thông tin, hãy xem lớp Ngẫu nhiên , tuy nhiên xin lưu ý:

Tuy nhiên, vì đồng hồ có độ phân giải hữu hạn, sử dụng hàm tạo không tham số để tạo các đối tượng Ngẫu nhiên khác nhau liên tiếp sẽ tạo ra các bộ tạo số ngẫu nhiên tạo ra các chuỗi số ngẫu nhiên giống hệt nhau

Vì vậy, không sử dụng mã này để tạo ra một loạt số ngẫu nhiên.


41
-1: Hạt giống mặc định dựa trên thời gian; làm điều này trong một vòng lặp và bạn sẽ nhận được kết quả rất ngẫu nhiên. Bạn nên tạo một trình tạo và sử dụng nó cho tất cả các số của bạn, không phải là một trình tạo riêng biệt mỗi lần.
Bevan

21
Này, thật không công bằng. Câu hỏi là làm thế nào để tạo số int ngẫu nhiên. Không có vòng lặp hoặc loạt đã được đề cập.
Fyodor Soikin

26
Ok, điểm công bằng. Đã giải quyết. Mặc dù vậy, tôi vẫn nghĩ rằng không sử dụng new Random()trong một vòng lặp là một điểm quan trọng.
Bevan

Đối với những người đi qua điều này trong tương lai, bây giờ nó đã rõ ràng, nhưng tôi sẽ chỉ ra điều đó; câu trả lời đã được cập nhật với điểm này, để không sử dụng điều này trong một vòng lặp cho nhiều giá trị.
vapcguy


30

Tôi muốn thêm một phiên bản bảo mật bằng mật mã:

Lớp RNGCryptoServiceProvider ( MSDN hoặc dotnetperls )

Nó thực hiện IDis Dùng một lần.

using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
   byte[] randomNumber = new byte[4];//4 for int32
   rng.GetBytes(randomNumber);
   int value = BitConverter.ToInt32(randomNumber, 0);
}

15

Bạn có thể sử dụng phương thức StaticRandom của Jon Skeet bên trong thư viện lớp MiscUtil mà anh ta đã xây dựng cho một số giả ngẫu nhiên.

using MiscUtil;
...

for (int i = 0; i < 100; 
    Console.WriteLine(StaticRandom.Next());

31
Tôi vừa xem mã nguồn và hàm này sử dụng chính xác cùng một công cụ số ngẫu nhiên, một công cụ "bao gồm" trong C #, nhưng đảm bảo rằng cùng một "đối tượng mẹ" / "đối tượng mẹ" được sử dụng cho tất cả các cuộc gọi. (Tôi xin lỗi vì tôi không biết thuật ngữ C #. Nhưng quan điểm của tôi là hàm này không tạo ra bất kỳ số ngẫu nhiên nào tốt hơn hàm tiêu chuẩn.)
Andreas Rejbrand

5
Không thể có bất cứ điều gì là 'thực sự ngẫu nhiên' vì luôn có một số yếu tố hạn chế hoặc định kiến ​​bao gồm vốn có bởi chính sự tồn tại của nó. Bạn đã không nghe giáo viên trong các lớp học khoa học? ;-)
Phill Healey

Hãy nói, theo anh ta điều này là 'thực sự ngẫu nhiên' như nó có được
Cậu bé Mitra

Liên kết bị hỏng ngay bây giờ. Đây là lý do tại sao bạn bao gồm thông tin bạn tìm thấy trong câu trả lời của bạn.
vapcguy

13

Tôi đã thử tất cả các giải pháp này trừ câu trả lời của COBOL ... lol

Không có giải pháp nào trong số này là đủ tốt. Tôi cần randoms trong một vòng lặp nhanh và tôi đã nhận được vô số giá trị trùng lặp ngay cả trong phạm vi rất rộng. Sau khi giải quyết loại kết quả ngẫu nhiên quá lâu, cuối cùng tôi quyết định giải quyết vấn đề này một lần và mãi mãi.

Đó là tất cả về hạt giống.

Tôi tạo một số nguyên ngẫu nhiên bằng cách phân tích các chữ số không phải từ Guid, sau đó tôi sử dụng số đó để khởi tạo lớp Random của mình.

public int GenerateRandom(int min, int max)
{
    var seed = Convert.ToInt32(Regex.Match(Guid.NewGuid().ToString(), @"\d+").Value);
    return new Random(seed).Next(min, max);
}

Cập nhật : Seeding không cần thiết nếu bạn khởi tạo lớp Random một lần. Vì vậy, tốt nhất là tạo một lớp tĩnh và gọi một phương thức tắt nó.

public static class IntUtil
{
   private static Random random;

   private static void Init()
   {
      if (random == null) random = new Random();
   }

   public static int Random(int min, int max)
   {
      Init();
      return random.Next(min, max);
   }
}

Sau đó, bạn có thể sử dụng lớp tĩnh như vậy ..

for(var i = 0; i < 1000; i++)
{
   int randomNumber = IntUtil.Random(1,100);
   Console.WriteLine(randomNumber); 
}

Tôi thừa nhận tôi thích cách tiếp cận này tốt hơn.


6
Guid không phải là ngẫu nhiên, nó không phải là một hạt giống tốt. GUID không đảm bảo về tính ngẫu nhiên, nó đảm bảo tính duy nhất xung quanh tính duy nhất. stackoverflow.com/questions/2621563/ cường
Magu

2
Guid là một hạt giống tốt. Tôi chỉ sử dụng các số trong Hướng dẫn. Hãy thử phương pháp cho chính mình. Đặt nó trong một vòng lặp dài và nhìn vào kết quả cho chính mình.
ProSenseo

1
Hmm, trên suy nghĩ thứ hai .. hạt giống không cần thiết chút nào. Cập nhật câu trả lời
ProSenseo

1
Điểm tuyệt vời trên bản cập nhật. Tôi thậm chí đã không nghĩ làm cho nó thành một trường tĩnh, cách này hoạt động tốt hơn nhiều và sạch sẽ hơn.
JCisar

1
Có một số vấn đề với câu trả lời này. Trước hết GUID không phải là một nguồn giống tuyệt vời - chỉ vì nó có vẻ ngẫu nhiên không có nghĩa là như vậy. Nó thể đủ tốt cho nhu cầu cá nhân của bạn. Thứ hai, lớp Random không phải là chủ đề an toàn. Bạn cần khởi tạo nó một lần trên mỗi luồng.
Hector

11

Các số được tạo bởi inbuilt Random lớp (System.Random) tạo ra các số ngẫu nhiên giả.

Nếu bạn muốn số ngẫu nhiên thực sự, gần nhất chúng ta có thể nhận được là "Trình tạo ngẫu nhiên giả an toàn" có thể được tạo bằng cách sử dụng các lớp Mật mã trong C #, chẳng hạn như RNGCryptoServiceProvider .

Mặc dù vậy, nếu bạn vẫn cần các số ngẫu nhiên thực sự, bạn sẽ cần sử dụng một nguồn bên ngoài, chẳng hạn như các thiết bị chiếm sự phân rã phóng xạ làm hạt giống cho một trình tạo số ngẫu nhiên. Vì theo định nghĩa, bất kỳ số nào được tạo ra bởi các phương tiện thuật toán thuần túy không thể thực sự ngẫu nhiên.


11

tạo một đối tượng ngẫu nhiên

Random rand = new Random();

và sử dụng nó

int randomNumber = rand.Next(min, max);

bạn không phải khởi tạo new Random()mỗi khi bạn cần một số ngẫu nhiên, bắt đầu một Ngẫu nhiên sau đó sử dụng số đó nhiều lần bạn cần trong một vòng lặp hoặc bất cứ điều gì


5
new Random()sử dụng bọ ve hiện tại làm hạt giống. Khi bạn khởi tạo nhiều trường hợp trong cùng một mili giây (trái ngược với đánh dấu), thì bạn sẽ nhận được cùng một giá trị được trả về.
Hans Ke st

10
Điều này là tích cực xấu. DateTime.Now.Millisecond (không giống DateTime.Now.Ticks) là một số trong khoảng từ 0 đến 999. Nếu bạn đang tạo một số mới cho mỗi số ngẫu nhiên, bạn sẽ chỉ có 1000 khả năng.
Oren Melzer

24 người đã nghĩ gì khi bỏ phiếu cho câu trả lời này ...?
Enigmativity

10

Câu trả lời sửa đổi từ đây .

Nếu bạn có quyền truy cập vào CPU tương thích Intel Secure Key, bạn có thể tạo các số và chuỗi ngẫu nhiên thực bằng các thư viện này: https://github.com/JebteK/RdRandhttps://www.rdrand.com/

Chỉ cần tải xuống phiên bản mới nhất từ đây , bao gồm Jebtek.RdRand và thêm một tuyên bố sử dụng cho nó. Sau đó, tất cả những gì bạn cần làm là:

// Check to see if this is a compatible CPU
bool isAvailable = RdRandom.GeneratorAvailable();

// Generate 10 random characters
string key       = RdRandom.GenerateKey(10);

 // Generate 64 random characters, useful for API keys 
string apiKey    = RdRandom.GenerateAPIKey();

// Generate an array of 10 random bytes
byte[] b         = RdRandom.GenerateBytes(10);

// Generate a random unsigned int
uint i           = RdRandom.GenerateUnsignedInt();

Nếu bạn không có CPU tương thích để thực thi mã, chỉ cần sử dụng các dịch vụ RESTful tại rdrand.com. Với thư viện trình bao bọc RdRandom có ​​trong dự án của bạn, bạn chỉ cần thực hiện việc này (bạn nhận được 1000 cuộc gọi miễn phí khi đăng ký):

string ret = Randomizer.GenerateKey(<length>, "<key>");
uint ret   = Randomizer.GenerateUInt("<key>");
byte[] ret = Randomizer.GenerateBytes(<length>, "<key>");

7

Tôi đã sử dụng mã dưới đây để có một số ngẫu nhiên (không khuyến nghị):

var random = new Random((int)DateTime.Now.Ticks);
var randomValue = random.Next(startValue, endValue + 1);

4

Trong khi điều này là ổn:

Random random = new Random();
int randomNumber = random.Next()

Bạn muốn kiểm soát giới hạn (tối thiểu và tối đa mumbers) hầu hết thời gian. Vì vậy, bạn cần xác định nơi số ngẫu nhiên bắt đầu và kết thúc.

Các Next() phương pháp chấp nhận hai tham số, min và max.

Vì vậy, nếu tôi muốn số ngẫu nhiên của mình nằm trong khoảng từ 5 đến 15, tôi chỉ cần làm

int randomNumber = random.Next(5, 16)

4

Đây là lớp tôi sử dụng. Hoạt động nhưRandomNumber.GenerateRandom(1, 666)

internal static class RandomNumber
{
    private static Random r = new Random();
    private static object l = new object();
    private static Random globalRandom = new Random();
    [ThreadStatic]
    private static Random localRandom;
    public static int GenerateNewRandom(int min, int max)
    {
        return new Random().Next(min, max);
    }
    public static int GenerateLockedRandom(int min, int max)
    {
        int result;
        lock (RandomNumber.l)
        {
            result = RandomNumber.r.Next(min, max);
        }
        return result;
    }
    public static int GenerateRandom(int min, int max)
    {
        Random random = RandomNumber.localRandom;
        if (random == null)
        {
            int seed;
            lock (RandomNumber.globalRandom)
            {
                seed = RandomNumber.globalRandom.Next();
            }
            random = (RandomNumber.localRandom = new Random(seed));
        }
        return random.Next(min, max);
    }
}

Lớp GenerateRandom của bạn sẽ không bao giờ trả về số 666, chỉ 665. Đây là sự hiểu lầm phổ biến (tính năng) của giá trị tối đa Random.Next.
Gordon Bell

3

Tôi muốn chứng minh điều gì xảy ra khi một trình tạo ngẫu nhiên mới được sử dụng mỗi lần. Giả sử bạn có hai phương thức hoặc hai lớp, mỗi lớp yêu cầu một số ngẫu nhiên. Và ngây thơ bạn mã họ như:

public class A
{
    public A()
    {
        var rnd=new Random();
        ID=rnd.Next();
    }
    public int ID { get; private set; }
}
public class B
{
    public B()
    {
        var rnd=new Random();
        ID=rnd.Next();
    }
    public int ID { get; private set; }
}

Bạn có nghĩ rằng bạn sẽ nhận được hai ID khác nhau? CHÂU ÂU

class Program
{
    static void Main(string[] args)
    {
        A a=new A();
        B b=new B();

        int ida=a.ID, idb=b.ID;
        // ida = 1452879101
        // idb = 1452879101
    }
}

Giải pháp là luôn luôn sử dụng một trình tạo ngẫu nhiên tĩnh duy nhất. Như thế này:

public static class Utils
{
    public static readonly Random random=new Random();
}

public class A
{
    public A()
    {
        ID=Utils.random.Next();
    }
    public int ID { get; private set; }
}
public class B
{
    public B()
    {
        ID=Utils.random.Next();
    }
    public int ID { get; private set; }
}

Làm thế nào để bạn an toàn chọn một hạt giống sau đó?
ja72

Chà, đầu tiên, nếu các đối tượng của bạn được tạo cách nhau thậm chí 10 ms, các số ngẫu nhiên được tạo sẽ khác với hạt giống mặc định. Thứ hai, bạn có thể nghiền bất kỳ dữ liệu môi trường hoặc xử lý ngẫu nhiên nào bạn có xung quanh để lấy hạt giống. Sau đó, có sự đánh đổi cho dù bạn muốn một chuỗi số dài rất có thể sẽ bắt đầu lặp lại chính nó, hoặc nhiều luồng ngay cả khi hai luồng kết thúc giống hệt nhau. Và nếu bạn quan tâm đến bảo mật, RNGCryptoServiceProviderdù sao thì cũng là một cuộc gọi tốt hơn.
Millie Smith

Sẽ thật tuyệt nếu có một chip ngẫu nhiên với nguồn phóng xạ hạt alpha nhỏ và máy dò (cách thức hoạt động của máy dò khói) để ngẫu nhiên các số dựa trên sự phân rã phóng xạ (rất ngẫu nhiên).
ja72

3

Đối với hạt giống ngẫu nhiên mạnh, tôi luôn sử dụng CryptoRNG chứ không phải Time.

using System;
using System.Security.Cryptography;

public class Program
{
    public static void Main()
    {
        var random = new Random(GetSeed());
        Console.WriteLine(random.Next());
    }

    public static int GetSeed() 
    {
        using (var rng = new RNGCryptoServiceProvider())
        {
            var intBytes = new byte[4];
            rng.GetBytes(intBytes);
            return BitConverter.ToInt32(intBytes, 0);
        }
    }
}

3
Random random = new Random ();
int randomNumber = random.Next (lowerBound,upperBound);

1
Mặc dù mã này có thể trả lời câu hỏi, tốt hơn là giải thích cách giải quyết vấn đề và cung cấp mã làm ví dụ hoặc tham chiếu. Câu trả lời chỉ có mã có thể gây nhầm lẫn và thiếu bối cảnh.
Robert Columbia

3

Chỉ là một lưu ý để tham khảo trong tương lai.

Nếu bạn đang sử dụng .NET Core, nhiều trường hợp Ngẫu nhiên không còn nguy hiểm như trước. Tôi biết rằng câu hỏi này có từ năm 2010, nhưng vì câu hỏi này đã cũ nhưng có một số điểm thu hút, tôi nghĩ rằng đó là một điều tốt để ghi lại sự thay đổi.

Bạn có thể tham khảo câu hỏi này tôi đã quay lại một lúc:

Microsoft đã thay đổi hạt giống mặc định ngẫu nhiên?

Về cơ bản, họ đã thay đổi hạt giống mặc định từ Environment.TickCountthànhGuid.NewGuid().GetHashCode() , vì vậy nếu bạn tạo 2 trường hợp Ngẫu nhiên, nó sẽ không hiển thị cùng một số.

Bạn có thể thấy tệp khác với .NET Framework / .NET Core (2.0.0+) tại đây: https://github.com/dotnet/coreclr/pull/2192/commits/9f6a0b675e5ac0065a268554de49162c539ff66d

Nó không an toàn như RNGCryptoServiceProvider, nhưng ít nhất nó sẽ không mang lại cho bạn kết quả kỳ lạ.


Điều này bây giờ đã lỗi thời. Có một phản ứng dữ dội đáng kể chống lại việc sử dụng Hướng dẫn. Mã bây giờ Interop.GetRandomBytes((byte*)&result, sizeof(int));.
Enigmativity

2

Các số được tính bởi một máy tính thông qua một quy trình xác định, theo định nghĩa, không thể là ngẫu nhiên.

Nếu bạn muốn có một số ngẫu nhiên thực sự, tính ngẫu nhiên đến từ tiếng ồn trong khí quyển hoặc sự phân rã phóng xạ.

Bạn có thể thử ví dụ RANDOM.ORG (nó làm giảm hiệu suất)


2
Random rand = new Random();
int name = rand.Next()

Đặt bất kỳ giá trị nào bạn muốn trong ngoặc đơn thứ hai, đảm bảo bạn đã đặt tên bằng cách viết prop và tab đôi để tạo mã


1
Prop và đôi tab?
DCShannon

Tại sao prop và đôi tab ? Bạn đang nói rằng không có phím tắt đó, đó là viết tắt của thuộc tính, mã của bạn sẽ không hoạt động?
Sнаđошƒаӽ

2

Nếu bạn muốn CSRNG tạo số ngẫu nhiên giữa tối thiểu và tối đa, thì đây là dành cho bạn. Nó sẽ khởi tạo Randomcác lớp với các hạt ngẫu nhiên an toàn.

    class SecureRandom : Random
    {
        public static byte[] GetBytes(ulong length)
        {
            RNGCryptoServiceProvider RNG = new RNGCryptoServiceProvider();
            byte[] bytes = new byte[length];
            RNG.GetBytes(bytes);
            RNG.Dispose();
            return bytes;
        }
        public SecureRandom() : base(BitConverter.ToInt32(GetBytes(4), 0))
        {

        }
        public int GetRandomInt(int min, int max)
        {
            int treashold = max - min;
            if(treashold != Math.Abs(treashold))
            {
                throw new ArithmeticException("The minimum value can't exceed the maximum value!");
            }
            if (treashold == 0)
            {
                throw new ArithmeticException("The minimum value can't be the same as the maximum value!");
            }
            return min + (Next() % treashold);
        }
        public static int GetRandomIntStatic(int min, int max)
        {
            int treashold = max - min;
            if (treashold != Math.Abs(treashold))
            {
                throw new ArithmeticException("The minimum value can't exceed the maximum value!");
            }
            if(treashold == 0)
            {
                throw new ArithmeticException("The minimum value can't be the same as the maximum value!");
            }
            return min + (BitConverter.ToInt32(GetBytes(4), 0) % treashold);
        }
    }

1

Xin lỗi, OP thực sự yêu cầu một intgiá trị ngẫu nhiên , nhưng với mục đích đơn giản là chia sẻ kiến ​​thức nếu bạn muốn một BigIntegergiá trị ngẫu nhiên, bạn có thể sử dụng câu lệnh sau:

BigInteger randomVal = BigInteger.Abs(BigInteger.Parse(Guid.NewGuid().ToString().Replace("-",""), NumberStyles.AllowHexSpecifier));

0

Tôi sẽ giả sử rằng bạn muốn một trình tạo số ngẫu nhiên phân phối đồng đều như dưới đây. Số ngẫu nhiên trong hầu hết các ngôn ngữ lập trình bao gồm C # và C ++ không được xáo trộn đúng cách trước khi sử dụng chúng. Điều này có nghĩa là bạn sẽ nhận được cùng một số nhiều lần, điều này không thực sự ngẫu nhiên. Để tránh vẽ cùng một số nhiều lần, bạn cần một hạt giống. Thông thường, đánh dấu thời gian là ok cho nhiệm vụ này. Hãy nhớ rằng bạn sẽ nhận được cùng một số nhiều lần nếu bạn đang sử dụng cùng một hạt giống mỗi lần. Vì vậy, hãy cố gắng sử dụng hạt giống khác nhau luôn. Thời gian là nguồn tốt cho hạt giống vì họ luôn luôn tán gẫu.

int GetRandomNumber(int min, int max)
{
    Random rand = new Random((int)DateTime.Now.Ticks);
    return rand.Next(min, max);
}

nếu bạn đang tìm kiếm trình tạo số ngẫu nhiên để phân phối bình thường, bạn có thể sử dụng phép chuyển đổi Box-Muller. Kiểm tra câu trả lời của yoyoyoyosef trong Câu hỏi biến ngẫu nhiên Gaussian. Vì bạn muốn số nguyên, bạn phải truyền giá trị gấp đôi cho số nguyên ở cuối.

Random rand = new Random(); //reuse this if you are generating many
double u1 = 1.0-rand.NextDouble(); //uniform(0,1] random doubles
double u2 = 1.0-rand.NextDouble();
double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) *
         Math.Sin(2.0 * Math.PI * u2); //random normal(0,1)
double randNormal =
         mean + stdDev * randStdNormal; //random normal(mean,stdDev^2)

Biến Gauss ngẫu nhiên


0

Cách dễ nhất có lẽ chỉ là Random.range(1, 3)Điều này sẽ tạo ra một số từ 1 đến 2.


-1

Bạn có thể thử với giá trị hạt ngẫu nhiên bằng cách sử dụng dưới đây:

var rnd = new Random(11111111); //note: seed value is 11111111

string randomDigits = rnd.Next();

var requestNumber = $"SD-{randomDigits}";

Cảm ơn @ MikaelDúiBolinder để xem snipet này
Rejwanul Reja

-2

Tại sao không sử dụng int randomNumber = Random.Range(start_range, end_range)?


Trên thực tế int RandomNumber = Random.Range (start_range, end_range + 1)
Gordon Bell

3
Random.Range () có tồn tại không? Tôi không thể tìm thấy nó trong tài liệu MSDN.
Phillip Ngân

Tôi cũng không thể tìm thấy Random.Range () trong tài liệu MSDN
user2455111

-2

Sử dụng một trường hợp ngẫu nhiên lặp đi lặp lại

// Somewhat better code...
Random rng = new Random();
for (int i = 0; i < 100; i++)
{
    Console.WriteLine(GenerateDigit(rng));
}
...
static int GenerateDigit(Random rng)
{
    // Assume there'd be more logic here really
    return rng.Next(10);
}

Bài viết này xem xét tại sao sự ngẫu nhiên gây ra rất nhiều vấn đề và làm thế nào để giải quyết chúng. http://csharpindepth.com/Articles/Ch CHƯƠNG12 / Random.aspx


Randomkhông phải là một lớp an toàn chủ đề. Nếu bạn tạo một thể hiện đơn lẻ, bạn nên hạn chế quyền truy cập vào nó sau một cơ chế khóa.
Brad M

-2

Hãy thử các bước đơn giản sau để tạo số ngẫu nhiên:

Tạo chức năng:

private int randomnumber(int min, int max)
{
    Random rnum = new Random();
    return rnum.Next(min, max);
}

Sử dụng chức năng trên ở một vị trí mà bạn muốn sử dụng các số ngẫu nhiên. Giả sử bạn muốn sử dụng nó trong một hộp văn bản.

textBox1.Text = randomnumber(0, 999).ToString();

0 là tối thiểu và 999 là tối đa. Bạn có thể thay đổi các giá trị thành bất cứ điều gì bạn muốn.


Điều này sẽ trả về cùng một số khi được gọi nhiều lần gần nhau khi nó sử dụng Thời gian hệ thống làm hạt giống ...
MOnsDaR

1
số ngẫu nhiên (0, 999) sẽ không bao giờ trả lại 999. Giá trị tối đa không bao gồm. Đây là sự hiểu lầm phổ biến (tính năng) của Random.Next giá trị tối đa.
Gordon Bell

-2

Tôi luôn có các phương thức tạo ra các số ngẫu nhiên giúp cho các mục đích khác nhau. Tôi hy vọng điều này cũng có thể giúp bạn:

public class RandomGenerator  
{  
    public int RandomNumber(int min, int max)  
    {  
        var random = new Random();  
        return random.Next(min, max);  
    }  

    public string RandomString(int size, bool lowerCase)  
    {  
        var builder = new StringBuilder();  
        var random  = new Random();  
        char ch;  

        for (int i = 0; i < size; i++)  
        {  
            ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));  
            builder.Append(ch);  
        }  

        if (lowerCase)  
            return builder.ToString().ToLower();  
        return builder.ToString();  
    }  
}

-3

Nhanh chóng và dễ dàng cho nội tuyến, sử dụng mã dưới đây:

new Random().Next(min, max);

// for example unique name
strName += "_" + new Random().Next(100, 999);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.