2012-12-18 39 views
5

Tôi làm việc trong C và tôi đang cố gắng tạo một bộ tạo ngẫu nhiên không chỉ tạo ra một số khác mỗi khi tôi chạy trình tạo nhưng cũng có một trình tự khác mỗi lần tôi chạy chương trình.Tôi đã kiểm tra hầu hết mọi thứ tôi tìm thấy trực tuyến. Tôi đã tạo ra 2 cách tốt để tạo ra một trình tạo ngẫu nhiên tốt. Đầu tiên là sử dụng một hạt giống khác nhau mỗi lần. Nhưng điều này có nghĩa rằng tôi phải sử dụng một hạt giống ngẫu nhiên khác nhau mỗi lần, một vấn đề mà tôi đã không giải quyết lúc đầu. Đây là những gì tôi đang cố gắng nhưng nó không thực sự ngẫu nhiên như tôi muốn:cố gắng tìm một trình tạo số ngẫu nhiên

int myrand(int random_seed){ 
    random_seed = random_seed * 1103515245 +12345; 
    return (unsigned int)(random_seed/65536) % 32768; 
          } 

Mỗi lần tôi gọi hàm i tăng hạt bằng cách 1.

cách thứ hai là sử dụng thay đổi time.Time và đây là randomness.I cũng đã cố gắng rất nhiều cách để thực hiện điều này. Thử mới nhất của tôi là ở đây: Compiler error-Possible IDE error"undefined reference to gettimeofday error" nhưng tôi không thể sử dụng chức năng gettimeofday vì tôi làm việc trong Windows.Cũng trong câu hỏi đó tôi không nhận được bất kỳ câu trả lời nào.

Bất cứ ai có thể giúp tôi làm thế nào tôi có thể thực hiện một máy phát điện ngẫu nhiên (có thể sử dụng thời gian) trong C làm việc trong Windows? Hoặc tôi nên sử dụng Unix?

+2

là một cái gì đó sai trái với 'srand()'? Bạn có thể gieo hạt giống như thế này: 'srand (time (NULL));' –

+0

tôi cũng đã thử srand (time (NULL)) nhưng tôi phải trì hoãn để chờ thời gian thay đổi. Lý do là tôi muốn tạo ra một số lượng lớn các số ngẫu nhiên trong một lần và tôi không muốn chờ 2 phút cho chương trình để tạo them.I cũng đã cố gắng sử dụng mili giây nhưng không thành công.Maybe mili giây là câu trả lời nhưng tôi không thể thực hiện nó đúng, một lần nữa vấn đề là tôi đang sử dụng windows. – Dchris

+2

@Dchris: hạt giống trình tạo số giả ngẫu nhiên (PRNG) của bạn với thời gian * một lần *, khi bắt đầu chương trình. Sau đó, bạn có thể phải đảm bảo không chạy chương trình của bạn nhiều hơn một lần mỗi giây (và giới thiệu mili giây sẽ giúp bạn), nhưng bạn không phải chờ một giây cho mỗi lần bạn đọc một số từ PRNG của bạn. –

Trả lời

4

Hạt giống RNG của bạn với nguồn entropy tốt.

Dưới dạng unix, sử dụng/dev/random.

Dưới cửa sổ, sử dụng giống như CryptoAPI - Windows equivalent of /dev/random

+1

Điều này chỉ dành cho tính ngẫu nhiên quan trọng. Việc đọc từ/dev/random sẽ làm cạn kiệt hệ thống entropy, điều này sẽ dẫn đến việc chặn khi nó cuối cùng trống rỗng, cho đến khi hệ thống thu thập được nhiều entropy hơn. Tất nhiên OP không nói liệu vấn đề anh ta đang cố giải quyết có liên quan đến an ninh hay không. Tôi nghi ngờ nó không phải. –

+0

thay đổi để lưu ý rằng bạn chỉ có thể gieo hạt theo cách đó. –

+1

Trên C++ 11, bạn có thể sử dụng ['std :: random_device'] (http://en.cppreference.com/w/cpp/numeric/random/random_device) mà có lẽ sẽ sử dụng bất kỳ nguồn dữ liệu ngẫu nhiên thực sự nào đang bật hệ thống. –

3

gì bạn đang yêu cầu không phải là một bộ tạo số ngẫu nhiên, nhưng làm thế nào để sử dụng máy phát số ngẫu nhiên đã có trong thư viện chuẩn C.

Tất cả bạn cần làm là hạt giống nó lần tại chương trình khởi động:

srand(time(NULL)); 

Đó là tất cả. Đó là di động và sẽ cung cấp cho bạn một chuỗi khác nhau mỗi khi bạn chạy chương trình, cho rằng ít nhất một giây đã trôi qua kể từ lần cuối bạn chạy nó.

Không có hại gì trong việc gieo hạt lại sau, nhưng cũng không có điểm nào trong đó.

+0

Không nên dùng lại nhẹ. Tùy thuộc vào việc chèn lại thuật toán PRNG có thể được mong muốn để tăng entropy nhưng chắc chắn có những cách đúng và sai để chèn sẵn và các cuộc tấn công mật mã dựa trên việc tái nhập lại kém. Như bạn đã nói lại việc sử dụng lại các trường hợp sử dụng PRNG đơn giản thường không cần thiết. Ví dụ, thuật toán MT có thể tạo ra một số 2^19937−1 đáng kinh ngạc trước khi nó lặp lại chính nó. Những cái khác là tốt đến 2^32 số trước khi đi xe đạp. – bot403

1

Thư viện chuẩn C có thời gian tiêu đề.h (hoặc ctime nếu bạn đang sử dụng C++) (reference). Các chức năng sẽ được hỗ trợ trong Windows và Unix.

Tôi muốn giới thiệu time() hoặc clock() làm hạt giống cho trình tạo số ngẫu nhiên của bạn.

Một cách khác để nhận được hoàn toàn ngẫu nhiên đầu vào là việc sử dụng vị trí chuột hoặc những thứ khác bị ảnh hưởng từ bên ngoài.

0

Có nhiều cách để thực hiện prng nhưng tiếc là không có cách nào trong số đó là trình tạo số ngẫu nhiên thực. thời gian (NULL) là một cách tiếp cận tốt nhưng tôi đang sử dụng "blum blum shub". Nó tạo ra một số ngẫu nhiên một số

0

Vì bạn đang yêu cầu một cách rõ ràng cho giải pháp Windows, tôi khuyên bạn nên tránh time(NULL) hoặc clock() làm hạt giống cho srand() vì độ chi tiết của chúng rất hạn chế (mili giây).Thay vào đó bạn có thể sử dụng kết quả của hiệu suất truy cập:

LARGE_INTEGER PerformanceCount; 
QueryPerformanceCounter(&PerformanceCount); 
srand(PerformanceCount.LowPart); 

Tỷ lệ tăng của tần số QueryPerformanceCounter() có thể thu được thông qua việc gọi QueryPerformanceFrequency(). Điều này thường tăng ít nhất 1 MHz và đôi khi thậm chí vào dải tần số GHz. Do đó, nó cung cấp nguồn thay đổi nhanh cho hạt giống.

Chỉnh sửa: Như được hiểu từ số earlier question cũng thực hiện gettimeofday() tương tự sẽ không cung cấp độ chi tiết cao. Nó có thể hiển thị từ tv_usec trong đối số của nó nhưng trên Windows, nó sẽ không cung cấp độ chi tiết micro giây như trên hệ thống Linux.

0

quote:

to make a random generator that not only generates a different number every time i run the generator

Định nghĩa của ngẫu nhiên không bao gồm khái niệm đó. Thay vào đó, ý tưởng là bạn có cơ hội bình đẳng để chọn bất kỳ số nào, bất kể số được chọn trước đó. Có nghĩa là về mặt lý thuyết có thể chọn cùng một số hai lần.

Nếu bạn đang xử lý một cỗ bài sau đó đáp ứng tiêu chí của bạn không có bản sao. Sử dụng phương pháp giao dịch boong có nghĩa là theo dõi các số "đã sử dụng".

Bạn cũng nên lưu ý rằng PNRG (trình tạo số giả ngẫu nhiên) là tuần hoàn (định kỳ). Sau khi bạn đã tạo số, thường là một số lớn, sau đó bạn bắt đầu lại từ đầu và lặp lại chính xác chuỗi tên của các số. Chức năng UNIX rand() tạo ra số nguyên số nguyên trong khoảng [0, {RAND_MAX}] và có một khoảng thời gian 2^32

Thật xem xét đọc trang ngắn này:

Xem: http://pubs.opengroup.org/onlinepubs/009695399/functions/rand.html

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