2012-06-26 19 views
5

Hãy để chúng tôi giải thích ý tôi là gì.Có phải rand() phụ thuộc vào thời gian trong php không?

Một số thời gian trước đây, khi viết một chương trình trong C#, tôi đã thực hiện sai lầm sau đây:

int Randomize() 
{ 
    Random r=new Random(); 
    return r.Next(0,10); 
} 

trong C#, đây là một sai lầm, bởi vì, gọi nhiều lần trong một hàng, chức năng này sẽ trở lại cùng một giá trị. Điều này là do hàm tạo ngẫu nhiên sử dụng hạt thời gian và sự khác biệt về thời gian giữa các cuộc gọi quá thấp (mất một giờ để tìm ra cái đó :)).

Bây giờ tôi đang sử dụng rand(...) trong php và tôi cần đầu ra luôn khác nhau, ngay cả khi 2 tập lệnh được thực hiện cùng một lúc.

Tôi có phải làm gì đó để có được kết quả này hay được thiết kế để hoạt động theo cách này không?

+0

Hãy để nó hoạt động, mặc dù mt_rand() tốt hơn rand() –

+0

Câu hỏi hay.Tôi không thể trả lời cụ thể một cách cụ thể, nhưng PRNG được chấp nhận của sự lựa chọn những ngày này là 'mt_rand', không phải là' rand'. – deceze

+0

Tốt nhất nhưng tôi nghĩ trong trường hợp của bạn rất khó để đảm bảo đầu ra khác nhau, ngay cả khi hai tập lệnh được thực thi cùng lúc –

Trả lời

9

rand() và cũng mt_rand() gọi srand()mt_srand() để tạo ra kết quả luôn luôn ngẫu nhiên. Nhưng đây là một bài thú vị trên php.net:

Lưu ý rằng các hạt giống tự động dường như được thực hiện với số lượng hiện tại giây có nghĩa là bạn có thể nhận được kết quả tương tự trong vài chạy trên một máy chủ nhanh. Hoặc gọi srand() cho mình với nhiều hơn hạt giống thường xuyên thay đổi hoặc sử dụng mt_rand() mà không xuất hiện để bị vấn đề.

Vì vậy, chỉ cần gọi srand thường xuyên hơn hoặc mt_rand.

+1

mặc dù không phải php, nhưng vẫn là một đọc tốt cho lý do tại sao tự động seeding có lẽ không phải là cách tiếp cận tốt nhất. http://baagoe.com/en/RandomMusings/javascript/ – Yoshi

3

Về mt_rand() chức năng ...

Từ http://php.net/manual/en/function.mt-srand.php

Tính đến PHP 4.2.0, không có nhu cầu để gieo rắc các máy phát điện số ngẫu nhiên với srand() hoặc mt_srand() vì đây là bây giờ được thực hiện tự động.

(Đối với PHP 5.2.1) Triển khai thực hiện Mersenne Twister trong PHP hiện sử dụng thuật toán tạo hạt giống mới của Richard Wagner. Hạt giống hệt nhau không còn tạo ra cùng một chuỗi các giá trị mà chúng đã làm trong các phiên bản trước. Hành vi này không được dự kiến ​​sẽ thay đổi một lần nữa, nhưng nó được coi là không an toàn để dựa vào nó dù sao.

Đây là link, với mô tả của "Mersenne Twister (MT)" số giả ngẫu nhiên thuật toán tạo ra (và implementations trong C, C++, C#)

Here bạn có thể tìm thấy thực hiện chức năng này trong PHP 5

Và trong php_rand.h tôi thấy điều này:

#ifdef PHP_WIN32 
#define GENERATE_SEED() (((long) (time(0) * GetCurrentProcessId()))^((long) (1000000.0 * php_combined_lcg(TSRMLS_C)))) 
#else 
#define GENERATE_SEED() (((long) (time(0) * getpid()))^((long) (1000000.0 * php_combined_lcg(TSRMLS_C)))) 
#endif 

Vì vậy, bây giờ bạn có thể thấy, các hàm ngẫu nhiên trong PHP dựa trên hàm time ...

+0

Ngoài ra, hãy xem 'lcg.c'. Nó phụ thuộc vào thời gian ** một lần ** nếu nó chưa được gieo hạt. Theo định nghĩa, lcg sẽ tạo ra một giá trị ngẫu nhiên mới sau mỗi cuộc gọi, và nó không phụ thuộc vào chức năng thời gian cho mỗi cuộc gọi. – Leigh

+0

@Làm ơn. Tôi đã bỏ lỡ điểm đó. Cảm ơn bạn. –

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