Sự khác biệt giữa Ngẫu nhiên thực (True Random) và Ngẫu nhiên giả lập (Pseudo-Random)
Bảng so sánh TRNG, PRNG, CSPRNG; seed, chu kỳ, Math.random() và crypto.getRandomValues(); dùng loại nào cho game, mật khẩu, bốc thăm.

True random và pseudo-random khác nhau ở nguồn tạo số: ngẫu nhiên thực (TRNG) đo tính bất định từ hiện tượng vật lý, còn ngẫu nhiên giả lập (PRNG) tính dãy số bằng thuật toán từ seed: cùng thuật toán, tham số và seed thì ra cùng dãy. CSPRNG là PRNG được thiết kế để khó đoán khi seed bí mật.
Trong thực tế ba loại thường đi cùng nhau. Nguồn vật lý (như nhiễu điện tử) cung cấp entropy để tạo seed, CSPRNG kéo dài seed đó thành nhiều byte cho mật khẩu và khoá mã hoá. PRNG thường lo mô phỏng và trò chơi vì nhanh và chạy lại được.
- Nguồn vật lýnhiễu điện tử, cung cấp entropy
- Seedtạo từ entropy đã thu
- CSPRNGkéo dài seed thành nhiều byte
- Đầu ramật khẩu, khoá mã hoá
Bảng so sánh TRNG, PRNG và CSPRNG
| Tiêu chí | TRNG (ngẫu nhiên thực) | PRNG (giả ngẫu nhiên) | CSPRNG (giả ngẫu nhiên an toàn mật mã) |
|---|---|---|---|
| Tính ngẫu nhiên đến từ đâu | Hiện tượng vật lý: nhiễu nhiệt, diode nhiễu, dao động mạch, phân rã phóng xạ | Thuật toán xác định + seed | Thuật toán xác định + seed lấy từ nguồn entropy tốt |
| Chạy lại có ra cùng dãy không | Không, mỗi lần đo là một mẫu mới | Có, nếu cùng thuật toán, tham số và seed | Có nếu biết seed và trạng thái, nhưng chúng được giữ bí mật |
| Người ngoài đoán được số tiếp theo không | Khó, nếu nguồn được đánh giá và kiểm tra | Được, nếu biết hoặc suy ra được trạng thái | Được thiết kế để việc đoán không khả thi khi seed bí mật và cài đặt đúng |
| Cần gì để chạy | Phần cứng đo, kiểm tra sức khoẻ nguồn, thường thêm bước xử lý | Chỉ cần phép tính | Phép tính + seed từ nguồn entropy |
| Ví dụ | Bộ sinh số phần cứng dựa trên nhiễu điện tử, thiết bị đo phân rã phóng xạ | LCG, Mersenne Twister, xorshift, Math.random() | crypto.getRandomValues() trong trình duyệt, crypto.randomInt() trong Node.js |
| Hợp với | Cấp seed cho CSPRNG, thiết bị cần nguồn entropy | Mô phỏng, kiểm thử, hiệu ứng, trò chơi không có tiền hay quyền lợi bị tranh chấp | Mật khẩu, token, mã xác minh, khoá, quay thưởng cần chống đoán trước |
Bảng không có hàng tốc độ cụ thể vì tốc độ phụ thuộc phần cứng, thuật toán và cách cài đặt; không có số đo chung đáng tin để so ba loại.
Ngẫu nhiên thực (TRNG) là gì?
TRNG (true random number generator) là bộ sinh số lấy tính bất định từ một quá trình vật lý thay vì từ phép tính. NIST gọi phần này là nguồn entropy, gồm nguồn nhiễu, các bài kiểm tra sức khoẻ và có thể có bước xử lý (conditioning) để làm đều đầu ra (NIST, Entropy Source).
Nguồn vật lý cũng có thể lệch hoặc hỏng, nên phải được đánh giá trước khi dùng và kiểm tra sức khoẻ trong lúc chạy. Vì vậy ứng dụng thường không đọc thẳng từng bit từ phần cứng mà gọi bộ sinh số của hệ điều hành hoặc trình duyệt, nơi entropy được dùng làm seed cho một CSPRNG.
Entropy đo mức khó đoán của một nguồn ngẫu nhiên (chính xác là của phân phối xác suất các kết quả nó có thể cho ra), tính bằng bit. Min-entropy là cách đo chỉ dựa vào kết quả dễ xảy ra nhất (NIST SP 800-90B):
Min-entropy
H = −log2(p_max)
p_max là xác suất của kết quả dễ xảy ra nhất.
Một con xúc xắc 6 mặt cân đối có p_max = 1/6, nên một lần gieo có log2(6) ≈ 2,585 bit min-entropy; nhiều lần gieo độc lập thì cộng dồn theo số lần. Xúc xắc bị lệch, mặt 6 ra 1/2 số lần, chỉ còn log2(2) = 1 bit.
- Xúc xắc cân đối,
p_max = 1/6≈ 2,585 bit - Xúc xắc lệch, mặt 6 ra 1/2 số lần1 bit
Ngẫu nhiên giả lập (PRNG) là gì?
PRNG (pseudorandom number generator) là thuật toán xác định nhận một seed và tạo ra dãy số dài trông như ngẫu nhiên (NIST, Pseudorandom Number Generator). Chữ "giả" không có nghĩa là gian lận: dãy số có thể phân bố rất đều, chỉ là nó được tính ra chứ không đo từ thế giới thật.
Seed và chu kỳ
Seed là trạng thái khởi đầu. Hai chương trình dùng cùng thuật toán, cùng tham số, cùng phiên bản và cùng seed 42 sẽ ra đúng một dãy. Với mô phỏng và kiểm thử, đây là ưu điểm: lưu seed lại là chạy lại được đúng thí nghiệm, tìm lại được lỗi xảy ra ở lần chạy thứ 300.
Trạng thái của PRNG có hữu hạn giá trị, nên đến một lúc dãy sẽ lặp lại. Độ dài trước khi lặp gọi là chu kỳ. Ví dụ minh hoạ với bộ sinh đồng dư tuyến tính nhỏ, x(n+1) = (2·x(n) + 1) mod 9, seed 0:
x1 = (2·0 + 1) mod 9 = 1x2 = (2·1 + 1) mod 9 = 3x3 = (2·3 + 1) mod 9 = 7x4 = (2·7 + 1) mod 9 = 15 mod 9 = 6x5 = (2·6 + 1) mod 9 = 13 mod 9 = 4x6 = (2·4 + 1) mod 9 = 9 mod 9 = 0, quay về seed. Dãy lặp lại sau 6 bước, dù có 9 giá trị khả dĩ: 2, 5 và 8 không bao giờ xuất hiện.
Đây chỉ là mô hình để thấy cơ chế, không dùng cho việc thật.
LCG, Mersenne Twister và xorshift
- LCG (linear congruential generator) cập nhật trạng thái bằng công thức
x(n+1) = (a·x(n) + c) mod m, như ví dụ trên. NIST dùng một LCG làm ví dụ trong bộ kiểm định SP 800-22 (NIST SP 800-22). Đơn giản, nhanh, nhưng chất lượng phụ thuộc nhiều vào chọna,c,m. - Mersenne Twister (MT19937) có chu kỳ
2^19937 − 1và được thiết kế chủ yếu cho mô phỏng Monte Carlo. Trang của chính tác giả ghi rõ nó không an toàn mật mã nếu dùng nguyên bản (Matsumoto và Nishimura). Chu kỳ dài không đồng nghĩa với khó đoán. - Xorshift là họ PRNG chỉ dùng phép dịch bit và XOR, rất nhanh, có cấu hình chu kỳ
2^k − 1(Marsaglia, 2003). Tốc độ và chu kỳ của nó cũng không biến nó thành CSPRNG.
CSPRNG là gì, có phải True Random không?
Không. CSPRNG (cryptographically secure PRNG) vẫn là PRNG, tức là thuật toán xác định, nhưng có thêm yêu cầu: khi seed không bị lộ, việc đoán đầu ra không khả thi về mặt tính toán (NIST). Nó không phải True Random.
Độ an toàn của CSPRNG có điều kiện; lộ trạng thái hay entropy yếu thì đầu ra có thể bị đoán.
CSPRNG chỉ khó đoán khi
- Seed lấy từ nguồn entropy tốt.
- Seed và trạng thái được giữ bí mật.
- Cài đặt đúng.
Trong trình duyệt, crypto.getRandomValues() trả về giá trị mạnh về mật mã, sinh từ một CSPRNG được seed bằng entropy chất lượng cao. Đặc tả không bắt buộc thuật toán cụ thể và mỗi lần gọi lấy tối đa 65.536 byte (W3C Web Cryptography API).
Gọi getRandomValues() là "true random" là không đúng, dù với ứng dụng web thông thường nó là lựa chọn chuẩn khi cần giá trị khó đoán.
Math.random() và crypto.getRandomValues() khác nhau thế nào?
Math.random() là PRNG thường, còn crypto.getRandomValues() là CSPRNG.
Math.random()
- Trả về số thực trong khoảng
[0, 1). - Bạn không chọn hay đặt lại seed được.
- Dùng cho hiệu ứng, trò chơi, chọn ngẫu nhiên thông thường.
crypto.getRandomValues()
- Không trả về một số mà điền đầy một mảng số nguyên bạn truyền vào (ví dụ
Uint8ArrayhayUint32Array). - Không cho đặt seed.
- Dùng cho mật khẩu, token, mã và chuỗi bí mật.
MDN ghi rõ không dùng Math.random() cho việc liên quan bảo mật (MDN, Math.random()). Đặc tả JavaScript cũng không quy định trình duyệt phải dùng thuật toán nào.
Khi tạo khoá mã hoá trong trình duyệt, W3C khuyên dùng generateKey() thay vì tự ghép byte từ getRandomValues().
Lỗi hay gặp: lấy phần dư làm lệch kết quả
Cần một số từ 0 đến 9 từ một byte (0–255), nhiều người viết byte % 10. Vì 256 không chia hết cho 10, các số 0–5 mỗi số ứng với 26 giá trị byte, còn 6–9 chỉ 25. Độ lệch này gọi là modulo bias (lệch do lấy phần dư).
byte % 10byte % 10Cách sửa phổ biến là lấy mẫu loại bỏ (rejection sampling): bỏ các byte từ 250 đến 255 rồi lấy byte khác, khi đó mỗi số 0–9 ứng với đúng 25 giá trị. Hàm crypto.randomInt() của Node.js đã làm việc này sẵn (Node.js crypto).
Nên dùng loại nào cho việc gì?
Dùng PRNG khi không ai được lợi nếu đoán trước kết quả (mô phỏng, trò chơi); dùng CSPRNG khi có (mật khẩu, token, khoá). Câu hỏi quyết định là: có ai được lợi nếu đoán trước kết quả không? Nếu có, dùng CSPRNG qua API chuẩn của hệ điều hành, trình duyệt hay ngôn ngữ, không tự viết.

- Mô phỏng, kiểm thử, nghiên cứu: PRNG có seed lưu lại được, để người khác chạy lại đúng kết quả.
- Trò chơi, hiệu ứng, chọn người cho vui trong lớp: PRNG có sẵn như
Math.random()là đủ, miễn không có tiền hay quyền lợi đáng để ai đó tìm cách đoán. - Mật khẩu, token đăng nhập, mã xác minh, mã mời: CSPRNG, kèm lấy mẫu loại bỏ khi chuyển byte thành ký tự.
- Khoá mã hoá: hàm tạo khoá của thư viện mật mã (trong trình duyệt là
generateKey()). - TRNG trực tiếp: phần lớn ứng dụng không cần gọi tới; nó nằm sau CSPRNG của hệ điều hành.
- Quay thưởng có giải giá trị: CSPRNG cho phần chọn, cộng thêm cách để người ngoài kiểm lại kết quả.
Vongquay.com dùng loại nào?
Vongquay.com dùng cả hai loại: PRNG Math.random() cho vòng quay thường, CSPRNG (crypto.getRandomValues(), crypto.randomInt()) cho tạo mật khẩu, livestream và lấy seed bốc thăm. Chi tiết từng tính năng (đối chiếu mã nguồn ngày 14/10/2026):
- Vòng quay thường chọn ô trúng bằng
Math.random()nhân với tổng độ rộng các ô, rồi mới tính đường quay để đĩa dừng đúng ô đó. Đây là PRNG trên trình duyệt của người bấm, đủ cho lớp học hay chọn món, không phải loại dùng cho bảo mật. Cách tính tỉ lệ từng ô khi các ô có trọng số khác nhau có ở bài công thức tính xác suất. - Tạo mật khẩu ngẫu nhiên dùng
crypto.getRandomValues()và lấy mẫu loại bỏ như mục trên. Mật khẩu được tạo trên thiết bị của bạn, không gửi lên máy chủ. - Vòng quay livestream chọn người trúng trên máy chủ bằng
crypto.randomInt()của Node.js, chỉ trong những người chưa trúng; chiến dịch khách tự quay cũng chọn phần thưởng theo trọng số bằng hàm này. - Bốc thăm online lấy seed từ
crypto.getRandomValues()(chỉ khi trình duyệt không có Web Crypto mới dùngMath.random()), rồi một PRNG có seed tính toàn bộ kết quả. Trước khi bốc, trang tự công bố mã băm SHA-256 của một lời khai gồm seed và dấu vân tay của danh sách. Xong lễ, ai có gói bằng chứng (lời khai, đầu vào, phiên bản thuật toán) thì băm lại và chạy lại được đúng kết quả. Ở đây tính tái lập của PRNG là thứ giúp kiểm chứng. - Quay số trên trang vòng quay số ngẫu nhiên cũng lấy seed theo cách đó rồi dùng PRNG có seed ở cả ba chế độ. Chỉ chế độ Trúng thưởng mới niêm phong bằng mã băm và có gói bằng chứng; Khoảng số và Danh sách không công bố mã.
Nhìn một dãy số có biết là True Random không?
Không. Một dãy từ PRNG tốt có thể qua các bài kiểm định thống kê, còn một nguồn vật lý bị lệch có thể trượt. NIST nói rõ bộ kiểm định SP 800-22 chỉ phát hiện được một số kiểu lệch, không thể chứng nhận một bộ sinh số phù hợp cho mật mã (NIST SP 800-22 Rev. 1a).
Muốn biết một bộ sinh số thuộc loại nào và dùng được cho việc gì, bạn phải xem thiết kế của nó. Cụ thể là nguồn entropy, seed lấy từ đâu và giữ ở đâu, thuật toán, cách cài đặt, và ai có lợi nếu đoán được kết quả.
Nguồn tham khảo
- NIST SP 800-90B: Recommendation for the Entropy Sources Used for Random Bit Generation
- NIST Glossary: Pseudorandom Number Generator
- NIST Glossary: Entropy Source
- NIST SP 800-22 Rev. 1a: A Statistical Test Suite for Random and Pseudorandom Number Generators
- W3C Web Cryptography API: getRandomValues()
- MDN: Math.random()
- Node.js: crypto.randomInt()
- Mersenne Twister, trang của Makoto Matsumoto
- George Marsaglia (2003), Xorshift RNGs, Journal of Statistical Software


