C 言語で乱数を生成する

胡金庫 2023年10月12日
  1. randsrand 関数を使って C 言語で乱数を生成する
  2. C 言語で乱数を生成するために randomsrandom 関数を使用する
  3. 関数 getrandom を用いて C 言語で乱数を生成する
C 言語で乱数を生成する

この記事では、C 言語で乱数を生成する方法をいくつか紹介します。

randsrand 関数を使って 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 言語で乱数を生成するために randomsrandom 関数を使用する

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
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C Operator