C 言語で乱数を生成する
-
rand
とsrand
関数を使って C 言語で乱数を生成する -
C 言語で乱数を生成するために
random
とsrandom
関数を使用する -
関数
getrandom
を用いて C 言語で乱数を生成する
この記事では、C 言語で乱数を生成する方法をいくつか紹介します。
rand
と srand
関数を使って C 言語で乱数を生成する
rand
関数は擬似乱数生成器を実装しており、[0, RAND_MAX]
の範囲の整数を与えることができます。rand
関数の背後にある生成アルゴリズムは決定論的であることに注意してください。したがって、ランダムなビットでシードされている必要があります。
rand
関数は擬似乱数発生器のシードに使用され、その後に rand
を呼び出すことでランダムな整数列が生成されます。しかし、rand
の実装では、一様にランダムなビットを生成することは期待できません。そのため、rand
関数は暗号の感度が高いアプリケーションで利用することは推奨されません。以下の例では、現在時刻の値をジェネレータの種としているが、これはランダム性の良いソースではありません。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX 100000
#define SIZE 100
#define NUMS_TO_GENERATE 10
int main() {
srand(time(NULL));
for (int i = 0; i < NUMS_TO_GENERATE; i++) {
printf("%d\n", rand() % MAX);
}
exit(EXIT_SUCCESS);
}
出力:
85084
91989
85251
85016
43001
54883
8122
84491
6195
54793
C 言語で乱数を生成するために random
と srandom
関数を使用する
C 標準ライブラリで利用可能なもう一つの擬似乱数生成器は random
関数の下に実装されています。この方法は rand
と比較して好ましい方法であるが、暗号アプリケーションは機密性の高いコードでは random
関数を利用すべきではありません。random
は引数を取らず、long int
型の整数を [0, RAND_MAX]
の範囲で返します。この関数は比較的質の良い乱数を生成するために、srandom
関数と一緒に使うのが望ましいです。
前の例と同様に、time
関数を用いて現在の時刻をシードとして渡していることに注意してください。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/random.h>
#define MAX 100000
#define SIZE 100
#define NUMS_TO_GENERATE 10
int main() {
srandom(time(NULL));
for (int i = 0; i < NUMS_TO_GENERATE; i++) {
printf("%ld\n", random() / MAX);
}
printf("\n");
exit(EXIT_SUCCESS);
}
出力:
91
2019
2410
11784
9139
5858
5293
17558
16625
3069
関数 getrandom
を用いて C 言語で乱数を生成する
getrandom
は Linux に特化した関数であり、以前に提供した 2つの方法よりもはるかに質の高いランダムビットを得ることができます。getrandom
は 3つの引数を取り、void
ポインタはランダムビットを格納するバッファを指し、バッファのサイズをバイト単位で指定し、特殊機能のフラグを指定します。
以下の例では、&tmp
がランダムビットを格納するバッファのアドレスとして渡された単一の符号なし整数を生成し、そのサイズを sizeof
演算子を用いて計算します。getrandom
がビットを取得するランダム性のソースは、まれに初期化されていない場合があります。関数 getrandom
の呼び出しはプログラムの実行をブロックします。このような場合にすぐにエラー値 -1
を返すようにするために、マクロ定義 GRND_NONBLOCK
を第 3 引数に渡します。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/random.h>
#include <time.h>
#define MAX 100000
#define SIZE 100
#define NUMS_TO_GENERATE 10
int main() {
unsigned int tmp;
getrandom(&tmp, sizeof(unsigned int), GRND_NONBLOCK) == -1
? perror("getrandom")
: "";
printf("%u\n", tmp);
exit(EXIT_SUCCESS);
}
934103271