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


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


1433
2018-04-24 23:09


gốc




Các câu trả lời:


Các Random lớp học được sử dụng để tạo số ngẫu nhiên. (Pseudo-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ữ Random ví dụ và sử dụng lại nó. Nếu bạn tạo các cá thể mới quá gần, chúng sẽ tạo ra cùng một chuỗi các số ngẫu nhiên khi trình tạo ngẫu nhiên được tạo hạt giống từ đồng hồ hệ thống.


1896
2018-04-24 23:19



Nhận xét không dành cho thảo luận mở rộng; cuộc hội thoại này đã đã chuyển sang trò chuyện. - deceze♦
Chỉ cần một lưu ý cho người dùng Unity C #, bạn phải chỉ định "System.Random ()" là Unity có một "UnityEngine.Random ()" mà xung đột (lưu ý rằng "UnityEngine.Random ()" không có khả năng tạo ngẫu nhiên số). Do tính 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
@JuniorM: Có, bạn có thể tạo tĩnh để tái sử dụng nó, nhưng bạn phải cẩn thận để bạn không truy cập nó từ nhiều luồng vì nó không phải là chủ đề an toàn (như thường lệ đối với bất kỳ lớp nào không được tạo chủ đề an toàn ). - Guffa
Thêm một cho nhận xét về việc giữ cùng một trường hợp 'Ngẫu nhiên'. Điều đó đã làm phiền tôi một thời gian. - AndyUK
Tôi nghĩ sẽ hữu ích khi thêm tuyên bố từ chối trách nhiệm rằng điều này không an toàn về mặt mã hóa, vì đây là câu hỏi phổ biến, chỉ trong trường hợp ai đó mù quáng cố gắng làm mật mã Random... - Daniel García Rubio


Mỗi khi bạn làm ngẫu nhiên mới () nó được khởi tạo. Điều này có nghĩa rằng 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 cá thể Random duy nhất và tiếp tục sử dụng Next trên cùng một cá thể.

//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);
    }
}

181
2017-10-04 11:52



Đây không phải là những gì @ Guffa đã nói trong câu trả lời của anh ấy 6 tháng trước? "Nếu bạn tạo các phiên bản mới quá gần, chúng sẽ tạo ra cùng một chuỗi số ngẫu nhiên" - Chris
@ Chris- Đó là đúng những gì bạn nói. Trong này tôi đã cung cấp việc thực hiện điều đó. Tôi nghĩ đó là một cách hay để làm điều đó. Nó hoạt động tốt hơn. - Pankaj Mishra
Đây là một triển khai thực hiện đồng bộ mã để sử dụng từ các chủ đề seval. Đó là 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 đơn luồng. - Guffa
nếu bạn sử dụng mã, bạn có thể nhận được một đoàn xe kéo ... - Offler
@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. Những gì tôi đang nói là nó có thể được đơn giản hóa cho điều này: // Chức năng để có được số ngẫu nhiên riêng tĩnh readonly ngẫu nhiên getrandom = new Random (); public static int GetRandomNumber (int phút, int max) {lock (getrandom) {// đồng bộ hóa getrandom trả về.Next (min, max); }} - Sean Worle


Câu hỏi trông 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 như tất cả mọi người đã đề nghị sử dụng lớp Random và một số đã gợi ý sử dụng lớp mã hóa RNG. Nhưng sau đó khi nào 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 trong triết lý 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 RED, GREEN và VÀNG những gì xảy ra trong nội bộ. Điều gì làm cho một người chọn màu đỏ hoặc màu vàng hoặc màu xanh lá cây?

c# Random

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, nó có thể được yêu thích màu sắc, màu may mắn và như vậy. Nói cách khác, một số kích hoạt ban đầu mà chúng ta gọi là RANDOM là SEED. SEED này là điểm bắt đầu, trigger kích hoạt anh ta để chọn giá trị RANDOM.

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

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

c# Random

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

* Lớp “Random” chỉ sinh ra số ngẫu nhiên PSEUDO và để tạo số ngẫu nhiên SECURE, chúng ta cần sử dụng lớp “RNGCryptoServiceProvider”.

c# Random

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

Random rnd= new Random();
int rndnumber = rnd.Next()

Trong khi lớp RNGCryptoServiceProvider sử dụng entropy của hệ điều hành để tạo ra các hạt giống. Hệ điều hành entropy là một giá trị ngẫu nhiên được tạo ra bằng cách sử dụng âm thanh, nhấp chuột và bàn phím timings, nhiệt temp vv. Dưới đây đi 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 hệ điều hành entropy xem video này https://www.youtube.com/watch?v=tCYxc-2-3fY   từ 11:20, nơi giải thích logic của entropy OS. Vì vậy, đưa vào các từ đơn giản RNG Crypto tạo ra các số ngẫu nhiên SECURE.


152
2018-06-14 06:27



không nên là byte của bạn [5] chỉ [4] khi ToInt32 phân tích cú pháp chỉ 4 byte? - Bernhard
Hãy suy nghĩ tôi tốt nghiệp đại học ngẫu nhiên sau khi đọc bài này - markthewizard1234
không phải là rg.GetBytes ()? thay vì rn? - Gaspa79
@ Gaspa79: Phải. Tôi đã chỉnh sửa câu trả lời. - zx485
Tôi ngẫu nhiên đến câu hỏi này và chỉ chứng ngộ trên Random. - Vikram Kumar


Hãy coi chừng điều đó new Random() được gieo vào 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ể dùng:

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

Để biết thêm thông tin, hãy xem Ngẫu nhiên lớp học, mặc dù 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 tham số để tạo các đối tượng ngẫu nhiên khác nhau trong kế tiếp tạo các trình tạo số ngẫu nhiên tạo ra các chuỗi 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 chuỗi số ngẫu nhiên.


73
2018-04-24 23:10



-1: Hạt 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 không ngẫu nhiên. Bạn nên tạo một máy phát điện và sử dụng nó cho tất cả các số của bạn, không phải một máy phát điện riêng biệt mỗi lần. - Bevan
Này, không công bằng. Câu hỏi đặt ra là cách tạo số int ngẫu nhiên. Không có vòng lặp hoặc chuỗi nào được đề cập đến. - Fyodor Soikin
Ok, điểm công bằng. Đã hủy bỏ. Mặc dù, tôi vẫn nghĩ rằng không sử dụng new Random() trong vòng lặp là một điểm quan trọng. - Bevan
(int.MaxValue + 1) tràn - carson
Cảm ơn bạn @carson, ai đó đã thêm +1 vì câu trả lời ban đầu được viết. - Fyodor Soikin


Random r = new Random();
int n = r.Next();

42
2018-04-24 23:10





Tôi muốn thêm một phiên bản mã hóa an toàn:

Lớp RNGCryptoServiceProvider (MSDN hoặc là dotnetperls)

Nó thực hiện IDisposable.

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

22
2017-12-18 21:02





tốt hơn là hạt giống đối tượng Random với mili giây hiện tại, để đảm bảo số ngẫu nhiên thực sự, và bạn hầu như sẽ không tìm thấy bản sao sử dụng nó nhiều lần

Random rand = new Random(DateTime.Now.Millisecond);

13
2017-11-01 12:30



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 cá thể trong cùng một mili giây (trái với dấu tick), thì bạn sẽ nhận được cùng một giá trị trả về. - Hans Kesting


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

using System;
using MiscUtil;

class Program
{
    static void Main(string[] args)
    {
        for (int i = 0; i < 100; i++)
        {
            Console.WriteLine(StaticRandom.Next());
        }
    }
}

12
2018-04-24 23:31



"thật sự ngẫu nhiên"? Nó hoạt động như thế nào? - Andreas Rejbrand
Tôi chỉ cần nhìn vào 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 "bao gồm" trong C #, nhưng đảm bảo rằng cùng một "hạt giống" / "đố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à chức năng này không tạo ra bất kỳ số ngẫu nhiên nào tốt hơn so với hàm chuẩn.) - Andreas Rejbrand
Không thể cho bất cứ điều gì là 'thật 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 đó là vốn có bởi sự tồn tại của nó. Bạn đã không nghe giáo viên trong các lớp khoa học chưa? ;-) - Phill Healey
Hãy nói rằng, theo anh ta điều này là "thật sự ngẫu nhiên" vì nó được - The Mitra Boy


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

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

Đó 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 từ Guid, sau đó tôi sử dụng nó để 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: Việc gieo hạt 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 nên tạo một lớp tĩnh và gọi phương thức đó.

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.


10
2018-05-19 21:19



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. stackoverflow.com/questions/2621563/… - Magu
Guid là một hạt giống tốt. Tôi chỉ sử dụng những con số trong Guid. Hãy thử phương pháp cho chính mình. Đặt nó trong một vòng lặp dài và xem kết quả cho chính mình. - Proximo
Hmm, trên suy nghĩ thứ hai .. hạt giống là không cần thiết ở tất cả. Đang cập nhật câu trả lời - Proximo
Điểm tuyệt vời về bản cập nhật. Tôi thậm chí không nghĩ rằng để làm cho nó một lĩnh vực tĩnh, cách này hoạt động tốt hơn và sạch hơn. - JCisar
Có một số vấn đề với câu trả lời này. Đầu tiên của tất cả GUID không phải là một nguồn giống tuyệt vời - chỉ vì nó trông ngẫu nhiên không có nghĩa là nó. Nó có 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 phải khởi tạo nó một lần cho mỗi chủ đề. - Hector