Trong bài viết này chúng ta sẽ cùng thảo luận về bộ sinh số ngẫu nhiên Random-number generator (RNG), cũng như là class System.Random. Bộ sinh số ngẫu nhiên rất quan trọng được dùng nhiều trong cuộc sống, trong nhiều lĩnh vực khác nhau như bảo mật (security), tài chính, sổ xố (lottery),…
– Đối với con người chúng ta thì việc nói ngay ra, sinh ra được một số ngẫu nhiên là dễ dàng và nhanh chóng, nhưng đối với máy tính thì việc sinh ra một số ngẫu nhiên không dễ dàng như vậy, vì nó cần dựa trên một yếu tố nào đó có sẵn, các yếu tố này được gọi là “hạt giống”.
– Bộ sinh số ngẫu nhiên được chia làm 2 loại:
#1/2: True random number generator
– Bộ sinh số thực sự, bộ sinh số này dựa trên các hiện tượng vật lý không dự đoán được để sinh số ngẫu nhiên.
– Hạt giống (seed): tiếng ồn không khí (atmospheric noise), tiếng ồn nhiệt (thermal noise), hiện tượng điện tử, lượng tử,… Ví dụ: bức xạ vũ trụ, phân rã phóng xạ, tiếng ồn khí quyển,…
– Nhược điểm của bộ sinh số này là sinh số chậm, bị giới hạn do cần thu hoạch các nguồn thông tin tự nhiên.
#2/2: Pseudo random number generator
– Bộ sinh số này dựa trên các giải thuật để sinh ra một chuỗi các số ngẫu nhiên, và từ số ngẫu nhiên này sinh ra số ngẫu nhiên khác.
– Bộ sinh số này dựa trên dựa trên một hạt giống đầu tiên, và hạt giống này có thể không ngẫu nhiên.
– Ưu điểm của bộ sinh số này là sinh số nhanh và không giới hạn. Và để tăng tính ngẫu nhiên cho bộ sinh số này, người ta có thể sử dụng các hạt giống thu được từ bộ sinh số thực (True random number generator).
– Trên đây là một vài điểm lý thuyết khá thú vị về bộ sinh số ngẫu nhiên, để dễ hình dung thì bây giờ chúng ta sẽ đi vào thực hành xem lớp tạo số ngẫu nhiên System.Random có gì.
– Để tạo số ngẫu nhiên, chúng ta cần lớp System.Random và có 2 cách khởi tạo như sau:
- Khi chúng ta khởi tạo đối tượng random bằng new System.Random() mà không truyền vào tham số thì hạt giống seed mặc định sẽ là System.Environment.TickCount()
System.Random random = new System.Random();
- Tạo đối tượng dựa trên hạt giống cung cấp sẵn, thay vì khởi tạo bằng constructor không tham số thì chúng ta sẽ sử dụng constructor có tham số new System.Random(Seed : 5). Nếu sử dụng cách này thì sau mỗi lần chạy thì kết quả số ngẫu nhiên mà chúng ta nhận được là giống nhau.
System.Random random = new System.Random(Seed: 5);
– Sau khi khởi tạo đối tượng random thì chúng ta có thể sinh số ngẫu nhiên bằng một số phương thức sau:
#1/3: Sinh số ngẫu nhiên là integer
– random.Next() : phương thức này sẽ sinh số bất kỳ với giá trị trả về là integer. Và điều đặc biệt là bộ sinh số này sẽ không sinh ra số âm, do đó số ngẫu nhiên sẽ nằm trong khoảng từ 0 ~ int.MaxValue (2.147.483.647)
– random.Next(maxValue: 100); : sử dụng có tham số maxValue: 100, thì các số ngẫu sinh sinh ra sẽ không quá 100, cao nhất là 99
– random.Next(minValue: 1000, maxValue: 100000) : truyền vào cả tham số minValue và maxValue để chỉ ra cận min (có thể bắt đầu từ số âm) ~ max được sinh ra của số ngẫu nhiên.
#2/3: Sinh số ngẫu nhiên là doube
random.NextDouble() : số ngẫu nhiên double có giá trị từ 0.0 đến 1.0
#3/3: Sinh số ngẫu nhiên là byte
random.NextBytes() : dùng phương thức này chúng ta cần phải khai báo một mảng byte với độ dài tùy ý, sau đó sẽ truyền mảng này làm tham số cho phương thức NextBytes(). Giá trị số ngẫu nhiên sinh ra bằng phương thức này có thể giống (trùng) nhau.
namespace MinhHoangBlog { class Program { static void Main(string[] args) { // Tạo đối tượng Random dựa trên Seed = System.Environment.TickCount System.Random random = new System.Random(); int num = System.Environment.TickCount; // Tạo đối tượng dựa trên hạt giống cung cấp sẵn //System.Random random = new System.Random(Seed: 5); // Sinh số integer ngẫu nhiên int rdInt1 = random.Next(); // 0 ~ 2.147.483.647 (int.MaxValue) int rdInt2 = random.Next(maxValue: 100); // 0 ~ 99 int rdInt3 = random.Next(minValue: 1000, maxValue: 100000); // min ~ max // Sinh số double ngẫu nhiên double rdDouble = random.NextDouble(); // 0.0 ~ 1.0 // Sinh số ngẫu nhiên vào mảng byte byte[] buffer = new byte[256]; // 256: số nguyên bất kỳ bất kỳ cho biết độ dài của mảng byte random.NextBytes(buffer); // sẽ sinh số ngẫu nhiên vào mảng byte này gồm 256 phần tử, và có thể TRÙNG NHAU } } }