2010-02-26 27 views
17

Làm thế nào là ngẫu nhiên đạt được với Math.random trong javascript? Tôi đã thực hiện một cái gì đó mà chọn giữa khoảng 50 tùy chọn khác nhau một cách ngẫu nhiên. Tôi tự hỏi làm thế nào thoải mái tôi nên được với việc sử dụng Math.random để có được sự ngẫu nhiên của tôi.Làm thế nào là ngẫu nhiên đạt được với Math.random trong javascript?

+2

@David: đó không phải là sự thật ngẫu nhiên như bạn biết. Được quy cho John von Neumann: * "Bất kỳ ai xem xét các phương pháp số học về tạo chữ số ngẫu nhiên, tất nhiên, trong trạng thái tội lỗi." * Họ đang sử dụng PRNG. Trình tạo số giả ngẫu nhiên. – cocotwo

+0

@cocotwo: điều đó không có nghĩa là tất cả JS phải là psuedo ngẫu nhiên, từ thông số Bob được đăng bên dưới, nó CÓ THỂ là ngẫu nhiên thực sự. Nó sẽ chỉ được thực hiện để sử dụng một RNG thực, mà không phải là khó khăn như nó đã từng được. –

+2

Như một số câu trả lời dưới đây nói, nó thực sự phụ thuộc vào những gì bạn muốn làm. Tôi nghi ngờ cho 99% trường hợp, 'Math.random' là tốt, nhưng nó có khả năng có thể được dự đoán. –

Trả lời

14

Từ thông số kỹ thuật:

ngẫu nhiên():

Trả về một giá trị số với dấu hiệu tích cực, lớn hơn hoặc bằng 0 nhưng nhỏ hơn 1, được chọn ngẫu nhiên hoặc giả ngẫu nhiên với khoảng thống nhất phân phối trên phạm vi đó, sử dụng thuật toán phụ thuộc triển khai hoặc chiến lược . Hàm này không có các đối số .

Vì vậy, câu trả lời là tùy thuộc vào công cụ JavaScript bạn đang sử dụng.

Tôi không chắc chắn liệu tất cả các trình duyệt có sử dụng cùng một chiến lược hay không hoặc chiến lược đó thật không may là

Sẽ ổn cho mục đích của bạn. Chỉ khi bạn đang thực hiện một số lượng lớn các số liệu, bạn sẽ bắt đầu thấy một mẫu

+0

@cocotow et al. Tôi đã tự hỏi thời tiết hay không rằng psudo-ngẫu nhiên là tốt hay không? như tôi đoán rằng porobobly của nó không đủ tốt cho vegas hay khoa học nhưng nó có đủ tốt cho nhu cầu hàng ngày không? (i làm osmething mà sẽ đưa ra quyết định cho tôi dựa trên một danh sách các decisisons có thể. – David

+4

Nó là đủ tốt cho nhu cầu hàng ngày, đó là những gì Javascript 'Math.random()' là cho. Đó là tốt. –

+0

@JohnFeminella Vui lòng xác định " nhu cầu hàng ngày " – user877329

2

Đó là 100% đủ ngẫu nhiên cho mục đích của bạn. Nó được gieo bởi thời gian, vì vậy mỗi khi bạn chạy nó, bạn sẽ nhận được kết quả khác nhau.

Dán này vào trình duyệt của bạn thanh địa chỉ ...

javascript:alert(Math.random() * 2 > 1); 

và nhấn [Enter] một vài lần ... Tôi đã "true, false, false, true" - ngẫu nhiên đủ :)

+1

Ví dụ mã của bạn không hiển thị ngẫu nhiên của bộ tạo ngẫu nhiên Như bạn đã giới thiệu một skew.Nó sẽ dẫn đến nhiều giá trị sai hơn so với giá trị thực sự.Một sự khác biệt rất nhỏ, nhưng vẫn là một ví dụ về cách bạn có thể làm giảm chất lượng của randomn bằng cách sử dụng nó sai. – Guffa

+0

Đúng ... nhưng nếu tôi có 50 hộp kiểm ... ngay cả * mẫu * mà tôi đưa ra sẽ đủ tốt cho câu hỏi của David. –

3

Việc thực hiện chính xác tất nhiên có thể khác nhau một chút tùy thuộc vào trình duyệt, nhưng tất cả đều sử dụng một số loại trình tạo số ngẫu nhiên giả. Mặc dù nó không thực sự ngẫu nhiên, nó chắc chắn đủ tốt cho tất cả các mục đích chung.

Bạn chỉ nên lo lắng về tính ngẫu nhiên nếu bạn đang sử dụng nó cho những thứ cần ngẫu nhiên tốt, như mã hóa hoặc mô phỏng một trò chơi may rủi, nhưng sau đó bạn sẽ khó sử dụng Javascript.

1

Đây là một overkill chút ... nhưng, tôi không thể cưỡng lại làm điều này :)

Bạn có thể thực hiện điều này trong thanh địa chỉ trình duyệt của bạn. Nó tạo ra một số ngẫu nhiên từ 0 đến 4, 100000 lần. Và xuất ra số lần mỗi số được tạo và số lần một số ngẫu nhiên theo sau số khác.

Tôi đã thực hiện việc này trong Firefox 3.5.2. Tất cả các con số dường như bằng nhau - cho thấy không có thiên vị, và không có mô hình rõ ràng trong cách các con số được tạo ra.

javascript: 
var max = 5; 
var transitions = new Array(max); 
var frequency = new Array(max); 
for (var i = 0; i < max; i++) 
{ 
    transitions[i] = new Array(max); 
} 
var old = 0, curr = 0; 
for (var i = 0; i < 100000; i++) 
{ 
    curr = Math.floor(Math.random()*max); 
    if (frequency[curr] === undefined) 
    { 
     frequency[curr] = -1; 
    } 
    frequency[curr] += 1; 
    if (transitions[old][curr] === undefined) 
    { 
     transitions[old][curr] = -1; 
    } 
    transitions[old][curr] += 1; 
    old = curr; 
} 
alert(frequency); 
alert(transitions); 
+1

Đây không phải là quá mức cần thiết - Hoàn toàn không đủ. Nhìn vào bản phân phối không cho bạn biết nhiều về chất lượng entropy, và như những người khác đã nói, hành vi chính xác là phụ thuộc vào việc thực hiện, vì vậy thử nghiệm Firefox 3.5.2 không nói gì về tình hình chung. –

11

Sử dụng Math.random() là tốt nếu bạn không tổng hợp trực thuộc Trung ương & sử dụng kết quả, ví dụ: cho OAuth.

Ví dụ: trang web của chúng tôi đã sử dụng Math.random() để tạo các chuỗi "nonce" ngẫu nhiên để sử dụng với OAuth. Bản gốc JavaScript library đã làm điều này bằng cách chọn một ký tự từ danh sách được xác định trước bằng cách sử dụng Toán.ngẫu nhiên(): ví dụ:

for (var i = 0; i < length; ++i) { 
    var rnum = Math.floor(Math.random() * chars.length); 
    result += chars.substring(rnum, rnum+1); 
} 

Vấn đề là, người dùng đã nhận được chuỗi nonce trùng lặp (thậm chí sử dụng một chiều dài 10 nhân vật - lý thuyết ~ 10^18 kết hợp), thường trong vòng một vài giây của nhau. Tôi đoán điều này là do Math.random() gieo từ dấu thời gian, là một trong những áp phích khác được đề cập.

+3

+1 để mô tả cách thức tạo dấu thời gian dựa trên việc tạo hạt giống có thể tạo ra số trùng lặp trong môi trường đồng thời. – Twilite

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