大きな乱数Cを生成する方法

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

私は2 ^ 64より小さい数(すなわち、100000000より小さい)を生成したくありません。

これをするのに役立つものはありますか?

9
[100000000 - 999999999]は900,000,000の異なる値です。これらの数値は、64ではなく、30ビットのオーダーです。
追加された 著者 chux,
2 ^ 64は999999999よりはるかに大きいです。
追加された 著者 undur_gongor,

6 答え

rAndom()は、64ビットシステムで64ビットであるべきlongを返します。あなたが32ビットシステムを使用している場合、次のことができます:

#include 

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;

あるいは、NIXシステムで/ dev/rAndomをあなたのバッファに読み込むことができます:

#include 
#include 
#include 
#include    

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;

A

12
追加された
私のpc RAND_MAX2 ^ 32 ではなく 2 ^ 31 です。
追加された 著者 Chiel ten Brinke,
num =(num << 32)| "もしあなたが32ビットであれば"、 RAND_MAX はおそらく2 ^ 31-1かそれよりはるかに少ないでしょう。次に、 num =(num << 32)| rand(); は、同じ位置にあるビットをクリアして、生の num を常に生成します。 num%(999999999 - 100000000)は、この問題を、一様分布の不足を犠牲にして、まだ分散させるのに役立ちます。
追加された 著者 chux,
より小さい数 u32 が一様に分布しているとすると、このような結合数は次のようになります。 u64 =(u32 << 32)| u32 もですか?
追加された 著者 this,
これにより、「100000000未満の数字を生成したくありません」という要件が満たされることはありません。
追加された 著者 undur_gongor,
より良いが、805933941(2 ^ 64-1 mod 899999999)を上回る数字は、以下の数字よりもやや低い可能性がある;-)
追加された 著者 undur_gongor,
100000000の下限と999999999の上限の乱数を生成するには、 num =(num%(999999999 - 100000000))+ 100000000; 行を追加します。
追加された 著者 David M. Syzdek,
rand()は、 2 ^ 32 では必要ない RAND_MAX によって制限されます。そして、あなたはまだ srand()に何かを渡す必要があります。 /dev/random 機能は、他のプラットフォーム
追加された 著者 Piotr Praszmo,

2つの4バイトのランダムな整数を組み合わせて8バイトの整数を生成することができます。

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

Since rand returns int, and sizeof(int) >= 4 on almost any modern platform, this code should work. I've added the << 0 to make the intent more explicit.

The masking with 0x00000000FFFFFFFF and 0xFFFFFFFF00000000 is to prevent overlapping of the bits in the two numbers in case sizeof(int) > 4.

編集

@Bantharは RAND_MAX は必ずしも 2 ^ 32 ではないとコメントしており、少なくとも 2 ^ 16 次の4バイトの数字を4つ組み合わせて確認してください。

uint64_t random = 
  (((uint64_t) rand() <<  0) & 0x000000000000FFFFull) | 
  (((uint64_t) rand() << 16) & 0x00000000FFFF0000ull) | 
  (((uint64_t) rand() << 32) & 0x0000FFFF00000000ull) |
  (((uint64_t) rand() << 48) & 0xFFFF000000000000ull);
9
追加された
オフラインで RAND_MAX2 ^ 32 である可能性は非常に低いです。 (2 ^ 32) - 1 である可能性があります。それでも、それは珍しいことです。おそらく(2 ^ 31)-1 (2 ^ 15)-1 という共通の値を持つ INT_MAX と同じです。 Cは RAND_MAX2 ^ 16 ではなく(2 ^ 15) - 1 以上に指定します。
追加された 著者 chux,
| の代わりに ^ を使用すると、マスキングについて心配する必要はありません。
追加された 著者 caf,

You're looking for a cryptographic-strength PRNG, like openssl/rand: http://www.openssl.org/docs/crypto/rand.html

7
追加された
2018年8月の openssl.org/docs/crypto/rand.html のリンクリンクのみの問題の1つです。
追加された 著者 chux,
または、Windows Vistaで BCryptGenRandom と高い。
追加された 著者 Alexey Frunze,
+ 1: rand()の出力を予測するのは非常に難しいことではありません)
追加された 著者 Frank Farmer,

You can make a large number L out of smaller numbers (e.g. A & B). For instance, with something like L = (2^ n)*A + B where ^ denotes exponentiation and n is some constant integer (e.g. 32). Then you code 1< (bitwise left-shift) for the power-of 2 operation.

だからあなたは小さな乱数の大きな乱数を作ることができます。

3
追加された
B の範囲が[0 ...(2 ^ n)-1]でない場合、 L =(2 ^ n)* A + B は問題です。 B の範囲が広い場合(さらには2のべき乗)、 L =(2 ^ n)* A ^ B を使用する方がよいでしょう。 L =(max_possible_value_of_B +(type_of_L)1)* A + B
追加された 著者 chux,
より小さい数 u32 が一様に分布しているとすると、このような結合数は次のようになります。 u64 =(u32 << 32)| u32 もですか?
追加された 著者 this,
@この。私はそう思いますが、数学者に尋ねるべきです。
追加された 著者 Basile Starynkevitch,
L、n、A、およびb という文字はどういう意味ですか?どうか説明できますか?
追加された 著者 Ameen,

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

3
追加された

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

1
追加された