2011-10-27 76 views
8

Tôi đang tìm cách tạo số ngẫu nhiên lớn theo thứ tự 2^64 trong C ... (100000000 - 999999999), để sử dụng trong thuật toán mã hóa khóa công cộng (như p và q).Cách tạo số ngẫu nhiên lớn C

Tôi không muốn tạo số nhỏ hơn 2^64 (nghĩa là nhỏ hơn 100000000).

Có điều gì có thể giúp tôi thực hiện việc này không?

+7

2^64 lớn hơn nhiều so với 999999999. –

Trả lời

11

random() trả về thời gian dài trên hệ thống 64 bit phải là 64 bit. Nếu bạn đang ở trên một hệ thống 32bit bạn có thể làm như sau:

#include <inttypes.h> 

uint64_t num; 

/* add code to seed random number generator */ 

num = rand(); 
num = (num << 32) | rand(); 

// enforce limits of value between 100000000 and 999999999 
num = (num % (999999999 - 100000000)) + 100000000; 

Ngoài ra trên một hệ thống NIX bạn có thể đọc/dev/random vào bộ đệm của bạn:

#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <inttypes.h> 

int fd; 
uint64_t num; 
if ((fd = open("/dev/random", O_RDONLY) == -1) 
{ 
    /* handle error */ 
}; 
read(fd, &num, 8); 
close(fd); 

// enforce limits of value between 100000000 and 999999999 
num = (num % (999999999 - 100000000)) + 100000000; 

Một

+5

'rand()' bị giới hạn bởi 'RAND_MAX' không cần thiết' 2^32'. Và, bạn vẫn cần một cái gì đó để chuyển đến 'srand()'. Chức năng '/ dev/random' cũng có sẵn trên [các nền tảng khác] (http://en.wikipedia.org/wiki//dev/random). –

+0

Điều này không đảm bảo yêu cầu "Tôi không muốn tạo số nhỏ hơn ... 100000000" được đáp ứng. –

+0

Thêm dòng 'num = (num% (999999999 - 100000000)) + 100000000;' để tạo một số ngẫu nhiên giới hạn dưới 100000000 và giới hạn trên của 999999999. –

7

Bạn đang tìm kiếm một PRNG mã hóa-sức mạnh, như openssl/rand: http://www.openssl.org/docs/crypto/rand.html

+1

Hoặc [BCryptGenRandom] (http://msdn.microsoft.com/en-us/library/aa375458%28v=VS.85%29.aspx) trên Windows Vista trở lên. –

+1

+1: sử dụng 'rand()' cho điều này là một lỗ hổng bảo mật (dự đoán đầu ra của 'rand()' không phải là thách thức khủng khiếp) –

3

Bạn có thể làm cho một số lượng lớn L ra các số nhỏ hơn (ví dụ A & B). Ví dụ: với một cái gì đó như L = (2^ n)*A + B trong đó^biểu thị lũy thừa và n là một số nguyên không đổi (ví dụ 32). Sau đó, bạn mã số 1<<n (bitwise left-shift) cho hoạt động power-of 2.

Vì vậy, bạn có thể tạo số lượng ngẫu nhiên lớn các số ngẫu nhiên nhỏ hơn.

+0

các chữ cái 'L, n, A và b' có nghĩa là gì? bạn có thể giải thích được không? – Ameen

+0

Giả sử số nhỏ hơn 'u32' được phân bố đồng đều, là một số kết hợp 'u64 = (u32 << 32) | u32'? – this

+0

@this. Tôi đoán là có, nhưng bạn nên hỏi một nhà toán học. –

9

Bạn có thể kết hợp hai 4-byte số nguyên ngẫu nhiên để tạo ra một 8-byte một:

#include <stdint.h> 
... 
uint64_t random = 
    (((uint64_t) rand() << 0) & 0x00000000FFFFFFFFull) | 
    (((uint64_t) rand() << 32) & 0xFFFFFFFF00000000ull); 

Kể từ rand lợi nhuận int, và sizeof(int) >= 4 trên hầu hết các nền tảng hiện đại, mã này nên làm việc. Tôi đã thêm << 0 để làm cho mục đích rõ ràng hơn.

Mặt nạ với 0x00000000FFFFFFFF0xFFFFFFFF00000000 là để ngăn sự chồng chéo của các bit trong hai số trong trường hợp sizeof(int) > 4.

EDIT

Kể từ @Banthar nhận xét rằng RAND_MAX không nhất thiết phải 2^32, và tôi nghĩ rằng nó được đảm bảo có ít nhất 2^16, bạn có thể kết hợp bốn số 2-byte chỉ để đảm bảo:

uint64_t random = 
    (((uint64_t) rand() << 0) & 0x000000000000FFFFull) | 
    (((uint64_t) rand() << 16) & 0x00000000FFFF0000ull) | 
    (((uint64_t) rand() << 32) & 0x0000FFFF00000000ull) | 
    (((uint64_t) rand() << 48) & 0xFFFF000000000000ull); 
+3

Nếu bạn sử dụng '^' để kết hợp các số thay vì '|', bạn không cần phải lo lắng về mặt nạ. – caf

3

Tôi biết tôi có thể sẽ bị OliCharlesworth b____slapped, nhưng sử dụng rand() với tỷ lệ và độ lệch. Đó là trong stdlib.h Để bao gồm toàn bộ phạm vi, bạn nên thêm nó vào một rand nhỏ hơn() để điền vào các khoảng trống trong ánh xạ.

-1

Hoặc, bạn có thể sử dụng hai trình tạo số ngẫu nhiên với các hạt INDEPENDENT và đặt các số đầu ra của chúng lại với nhau như được đề xuất. Điều đó phụ thuộc vào việc bạn muốn có một số 64 bit của một RNG với một khoảng thời gian trong khoảng 2^64. Chỉ cần không sử dụng các cuộc gọi mặc định mà phụ thuộc vào thời gian, bởi vì bạn sẽ nhận được giống hệt nhau cho mỗi máy phát điện. Đúng cách, tôi chỉ không biết ...