2011-10-27 14 views
8

私は2^64のオーダーで大きな乱数を生成する方法を探しています...(100000000 - 999999999)、公開鍵暗号アルゴリズムで使用するpおよびq)。大きな乱数を生成する方法C

2^64より小さい(つまり、100000000より小さい)数値を生成したくありません。

これを行うのに役立つことはありますか?

+7

2^64は999999999よりはるかに大きいです。 –

答えて

11

random()は、64ビットシステムで64ビットであるべきlongを返します。あなたのバッファに/ dev/randomを読むことができるNIXシステム上の別

#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; 

:あなたは32ビットのシステム上にある場合は、次の操作を行うことができ

#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; 

+5

'rand()'は 'RAND_MAX'によって制限され、' 2^32'は不要です。そして、 'srand()'に渡すものがまだ必要です。 '/ dev/random'機能は[他のプラットフォーム]でも利用できます(http://en.wikipedia.org/wiki//dev/random)。 –

+0

これは、「100000000より小さい番号を生成したくありません」という要件を満たしているとは限りません。 –

+0

100000000の下限と999999999の上限の乱数を生成するには、 'num =(num%(999999999 - 100000000))+ 100000000;'行を追加してください。 –

7

あなたはopenssl/randのように、暗号強度PRNGを探しています:http://www.openssl.org/docs/crypto/rand.html

+1

または[BCryptGenRandom](http://msdn.microsoft.com/en-us/library/aa375458%28v=VS.85%29.aspx)Windows Vista以上。 –

+1

+1: 'rand()の出力を予測するのは大変難しいことではありません) –

3

あなたは小さい数字(例えばA & B)のうちの多数Lを作ることができます。例えば、L = (2^ n)*A + Bのようなものであり、ここで^は累乗を表し、nは一定の整数(例えば32)である。次に、2の累乗演算に対して、1<<n(ビット左シフト)をコーディングします。

したがって、小さな乱数の乱数を大きくすることができます。あなたは8バイトの1を生成するために、2つの4バイトの整数の乱数を組み合わせることができ

+0

' L、n、A、bという文字は何を意味していますか?どうか説明できますか? – Ameen

+0

「u32」が一様に分布していると仮定すると、そのような結合数は「u64 =(u32 << 32)| u32'も? – this

+0

@this。私はそう思いますが、数学者に尋ねるべきです。 –

9

rand戻りint、そしてほぼすべての近代的なプラットフォーム上sizeof(int) >= 4ので

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

を、このコードは動作するはずです。インテントをより明示的にするために<< 0を追加しました。

0x00000000FFFFFFFF0xFFFFFFFF00000000のマスキングは、sizeof(int) > 4の2つの数字のビットの重なりを防ぐためです。

EDIT

@BantharがRAND_MAXは必ずしも2^32ではないとコメントし、私は少なくとも2^16あることが保証されていると思うので、あなたは、念のために4つの2バイトの数字を組み合わせることができ:

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

'^'の代わりに '^'を使用すると、マスキングについて心配する必要はありません。 – caf

3

私はおそらく、OliCharlesworthによってb____slappedが得られると知っていますが、スケールとオフセットを付けてrand()を使用してください。それはstdlib.hにあります。範囲全体をカバーするためには、マッピングのギャップを埋めるために別の小さなrand()にそれを追加する必要があります。

-1

あるいは、独立した種を持つ2つの乱数ジェネレータを使用し、提案されたように出力番号をまとめることができます。これは、2^64の範囲のピリオドを持つRNGの64ビット数を使用するかどうかによって異なります。時間に依存するデフォルトの呼び出しを使用しないでください。これは、各ジェネレータに同じシードが得られるからです。正しい方法では、わかりません...

関連する問題