2010-12-14 41 views
11

Vì máy tính không thể chọn số ngẫu nhiên (có thể chúng?) Số ngẫu nhiên này được tạo ra như thế nào. Ví dụ: trong C# chúng tôi nói,Số ngẫu nhiên được tạo ra khi chạy như thế nào?

Random.Next() 

Điều gì xảy ra bên trong?

+5

Tìm kiếm - đã có hàng tá câu trả lời cho câu hỏi này. – RogerG

+0

đây là một chủ đề khác đề cập đến yêu cầu thực hiện as3 của random.next: http://stackoverflow.com/questions/3930291/actionscript-3-implementation-of-random-next cũng có các đoạn mã bên trong –

+1

@RogerG> Bạn có liên kết để chia sẻ không? Bởi vì tôi không thấy bất kỳ ... @hacticks> cảm ơn rất nhiều – naveen

Trả lời

14

Bạn có thể thanh toán this article. Theo số documentation, việc triển khai cụ thể được sử dụng trong .NET dựa trên thuật toán tạo số ngẫu nhiên của Donald E. Knuth. Để biết thêm thông tin, xem D. E. Knuth. "The Art of Computer Programming, volume 2: Seminumerical Algorithms". Addison-Wesley, Reading, MA, second edition, 1981.

+1

Đó là một bài viết thực sự tốt --- và nó bao gồm một số liên kết đến mã nguồn cho thấy một một số PRNG cũng rất tuyệt vời. +1 –

+0

cảm ơn rất nhiều ... rất toàn diện – naveen

2

Lớp Randompseudo-random number generator.

Về cơ bản, chuỗi lặp lại rất dài nhưng xác định. "Sự ngẫu nhiên" xuất phát từ các vị trí khác nhau. Chỉ định nơi bắt đầu được thực hiện bằng cách chọn một seed cho trình tạo số ngẫu nhiên và có thể ví dụ được thực hiện bằng cách sử dụng thời gian hệ thống hoặc bằng cách lấy một hạt giống ngẫu nhiên từ một nguồn ngẫu nhiên khác. default Random constructor sử dụng thời gian hệ thống làm hạt giống.

Thuật toán thực tế sử dụng để tạo ra các chuỗi các con số được ghi chép lại trong MSDN:

Việc thực hiện của lớp Random dựa trên thuật toán tạo số ngẫu nhiên trừ Donald E. Knuth. Để biết thêm thông tin, xem D. E. Knuth. "Nghệ thuật Lập trình Máy tính, tập 2: Thuật toán Seminumerical". Addison-Wesley, Reading, MA, ấn bản thứ hai, 1981.

+0

Vì vậy, người ta sẽ không muốn sử dụng lớp C# Random cho các chức năng mã hóa, sau đó, nó có vẻ như thế nào? Tôi đoán rằng sẽ có một số loại API có sẵn để có được con số như vậy, hoặc sẽ yêu cầu sử dụng một chức năng Win32 thông qua P/Invoke? –

+1

@Michael Trausch: Bạn có thể muốn xem xét RandomNumberGenerator thay vì cho mục đích mã hóa: http://msdn.microsoft.com/en-US/library/system.security.cryptography.randomnumbergenerator.aspx –

0

Tôi không biết nhiều chi tiết nhưng những gì tôi biết là một hạt giống được sử dụng để tạo ra các số ngẫu nhiên sau đó dựa trên một số thuật toán sử dụng hạt giống đó thu được một số mới.

Nếu bạn nhận được số ngẫu nhiên dựa trên cùng một hạt giống, chúng sẽ giống nhau thường xuyên.

1

Máy tính sử dụng pseudorandom number generators. Về cơ bản, chúng hoạt động bằng cách bắt đầu với một số hạt giống và lặp lại nó thông qua một thuật toán mỗi khi có một số giả ngẫu nhiên mới. Dĩ nhiên, quá trình này sẽ tạo ra chính xác cùng một chuỗi số mỗi khi nó được sử dụng, nhưng các con số được tạo thành một phân bố thống kê thống kê (khoảng), và điều này là tốt, vì trong hầu hết các kịch bản bạn cần là ngẫu nhiên ngẫu nhiên.

Thực hành thông thường là sử dụng thời gian hệ thống hiện tại làm hạt mầm, mặc dù cần bảo mật hơn, "entropy" có thể được thu thập từ nguồn vật lý như độ trễ đĩa để tạo hạt giống khó hơn dự đoán. Trong trường hợp này, bạn cũng muốn sử dụng một số cryptographically strong random number generator chẳng hạn như this.

5

Kể từ khi máy tính không thể chọn số ngẫu nhiên (có thể họ?)

Như những người khác đã lưu ý, "Ngẫu nhiên" thực sự là giả ngẫu nhiên. Để trả lời câu hỏi cha mẹ của bạn: có, máy tính có thể chọn số thực sự ngẫu nhiên. Làm như vậy sẽ đắt hơn nhiều so với số học số nguyên đơn giản của trình tạo số giả ngẫu nhiên và thường không bắt buộc. Tuy nhiên, có những ứng dụng mà bạn phải có tính ngẫu nhiên thực sự không thể dự đoán được: mật mã và poker trực tuyến ngay lập tức được lưu ý.Nếu sử dụng một nguồn giả ngẫu nhiên có thể đoán trước thì kẻ tấn công có thể giải mã/giả mạo các thông điệp dễ dàng hơn nhiều và các gian lận có thể tìm ra ai có những gì trong tay họ.

Lớp crypto .NET có methods that give random numbers suitable for cryptography hoặc trò chơi có tiền trên đường. Đối với cách họ làm việc: các tài liệu về tính ngẫu nhiên cường độ mã hóa là mở rộng; tham khảo bất kỳ sách giáo khoa đại học tốt về mật mã học để biết chi tiết.

Phần cứng đặc biệt cũng tồn tại để nhận các bit ngẫu nhiên. Nếu bạn cần số ngẫu nhiên được rút ra từ tiếng ồn không khí, xem www.random.org.

+2

Tất cả RNG dựa trên máy tính/logic là giả ngẫu nhiên * trừ khi * chúng có nguồn ngẫu nhiên thực sự. Một nguồn ngẫu nhiên sẽ giống như phân rã phóng xạ. Một số phần cứng máy tính có các trình tạo số ngẫu nhiên có các bóng bán dẫn ở trạng thái không ổn định và tạo ra một dòng các bit ngẫu nhiên không đổi. Sự khác biệt giữa giả ngẫu nhiên và ngẫu nhiên là giả ngẫu nhiên là xác định nhưng kéo dữ liệu từ nhiều nguồn là rất khó dự đoán và thật sự ngẫu nhiên ngay cả khi bạn biết tất cả các nguồn, bạn vẫn không thể biết đầu ra cho đến khi nó xảy ra. – Bengie

+0

@ Bengie: Tôi tin rằng các lớp mã hóa lấy được entropy của chúng từ các nguồn như thời gian nhấn phím và vân vân. Đó là những điều ngẫu nhiên khi bạn cần chúng cho mục đích thực tế. –

+0

thanka rất nhiều .. – naveen

4

Knuth đề cập đến chủ đề ngẫu nhiên rất tốt.

Chúng tôi thực sự không hiểu rõ lắm. Làm thế nào một cái gì đó có thể dự đoán được ngẫu nhiên? Và các chuỗi giả ngẫu nhiên có thể xuất hiện ngẫu nhiên hoàn toàn bằng các bài kiểm tra thống kê.

Có ba loại máy phát ngẫu nhiên, khuếch đại trên nhận xét ở trên.

Đầu tiên, bạn có trình tạo số ngẫu nhiên giả, nếu bạn biết số ngẫu nhiên hiện tại, thật dễ dàng để tính số tiếp theo. Điều này làm cho nó dễ dàng để đảo ngược kỹ sư số khác nếu bạn tìm ra một vài.

Sau đó, có các thuật toán mã hóa khiến việc này trở nên khó khăn hơn nhiều. Tôi tin rằng chúng vẫn là những chuỗi giả ngẫu nhiên (trái với những gì bình luận ở trên ngụ ý), nhưng với thuộc tính rất quan trọng mà biết một vài số trong chuỗi KHÔNG làm cho nó rõ ràng như thế nào để tính toán phần còn lại. Cách thức hoạt động của nó là thói quen mã hóa có xu hướng băm lên con số, để nếu một bit thay đổi, thì mỗi bit có khả năng thay đổi như nhau.

Hãy xem xét một máy phát điện modulo đơn giản (tương tự như một số triển khai trong C rand())

int rand() { trở lại hạt giống = hạt giống * m + a; }

nếu m = 0 và a = 0, đây là máy phát điện tệ hại với khoảng thời gian 1: 0, 0, 0, 0, .... nếu m = 1 và a = 1, nó cũng không phải tìm kiếm ngẫu nhiên: 0, 1, 2, 3, 4, 5, 6, ...

Nhưng nếu bạn chọn m và a là số nguyên khoảng 2^16, điều này sẽ nhảy xung quanh độc đáo trông rất ngẫu nhiên nếu bạn đang kiểm tra tình cờ. Nhưng bởi vì cả hai con số là lẻ, bạn sẽ thấy rằng bit thấp sẽ chuyển đổi, tức là số lượng luân phiên lẻ và thậm chí. Không phải là trình tạo số ngẫu nhiên tuyệt vời. Và vì chỉ có 2^32 giá trị trong một số 32 bit, theo định nghĩa sau 2^32 lần lặp lại nhiều nhất, bạn sẽ lặp lại trình tự một lần nữa, làm cho nó rõ ràng là máy phát KHÔNG phải ngẫu nhiên.

Nếu bạn nghĩ rằng các bit ở giữa là đẹp và tranh giành, trong khi các bit ở giữa không giống như ngẫu nhiên, thì bạn có thể tạo một trình tạo số ngẫu nhiên tốt hơn trong số này, với các bit XORed khác nhau sao cho tất cả các bit đều được bảo vệ tốt. Một cái gì đó như:

(rand1() >> 8)^rand2()^(rand3()> 5) ...

Tuy nhiên, mỗi số được lật đồng bộ, mà làm cho dự đoán này. Và nếu bạn nhận được hai giá trị tuần tự thì chúng tương quan nhau, để nếu bạn vẽ chúng, bạn sẽ nhận được các dòng trên màn hình của bạn. Bây giờ hãy tưởng tượng bạn có các quy tắc kết hợp các máy phát, do đó các giá trị tuần tự không phải là các giá trị tiếp theo. Ví dụ:

v1 = rand1() >> 8^rand2() ... v2 = rand2() >> 8^rand5() ..

và tưởng tượng rằng các hạt không phải lúc nào cũng thăng tiến. Bây giờ bạn bắt đầu tạo ra một thứ khó dự đoán hơn dựa trên kỹ thuật đảo ngược, và trình tự dài hơn.

Ví dụ: nếu bạn tính toán rand1() mỗi lần, nhưng chỉ tiến hành hạt giống trong rand2() mỗi lần thứ ba, máy phát điện kết hợp chúng có thể không lặp lại lâu hơn thời gian của một.

Bây giờ hãy tưởng tượng rằng bạn bơm bộ tạo số ngẫu nhiên loại modulo (khá dự đoán được) thông qua DES hoặc một số thuật toán mã hóa khác. Điều đó sẽ tranh giành các bit.

Rõ ràng, có các thuật toán tốt hơn, nhưng điều này mang lại cho bạn ý tưởng. Bí quyết số có rất nhiều thuật toán được thực hiện trong mã và giải thích. Một mẹo rất hay: tạo ra không chỉ một khối mà là một khối các giá trị ngẫu nhiên trong một bảng. Sau đó, sử dụng trình tạo số ngẫu nhiên độc lập để chọn một trong các số được tạo, tạo một số mới và thay thế nó. Điều này phá vỡ bất kỳ mối tương quan nào giữa các cặp số liền kề.

Phạm trù thứ ba là máy phát điện số ngẫu nhiên dựa trên phần cứng thực tế, ví dụ dựa trên tiếng ồn khí quyển

http://www.random.org/randomness/

Đây là, theo khoa học hiện nay, thật sự ngẫu nhiên. Có lẽ một ngày nào đó chúng ta sẽ khám phá ra rằng nó tuân theo một số quy tắc cơ bản, nhưng hiện tại, chúng ta không thể dự đoán được những giá trị này, và chúng thực sự ngẫu nhiên như chúng ta quan tâm.

Thư viện tăng cường đã triển khai C++ xuất sắc của máy tạo Fibonacci, các vị vua trị vì các chuỗi giả ngẫu nhiên nếu bạn muốn xem một số mã nguồn.

4

tôi sẽ chỉ cần thêm một câu trả lời cho phần đầu của câu hỏi (the "có thể họ?" Phần) .h

Computers thể tạo (tốt, tạo có thể không phải là một hoàn toàn chính xác từ) số ngẫu nhiên (như trong, không giả ngẫu nhiên). Cụ thể, bằng cách sử dụng ngẫu nhiên môi trường được nhận thông qua các thiết bị phần cứng chuyên dụng (tạo ra sự ngẫu nhiên dựa trên nhiễu, ví dụ) hoặc bằng cách sử dụng đầu vào môi trường (ví dụ: thời gian ổ đĩa cứng, thời gian sự kiện đầu vào của người dùng).

Tuy nhiên, điều đó không ảnh hưởng đến câu hỏi thứ hai (đó là cách hoạt động của Random.Next()).

Các vấn đề liên quan