USB4とは何か? パソコン購入前に知っておきたいポイントを整理
USB4とは何かを、パソコン購入前に知っておきたい人向けに整理します。Thunderbolt 4 / 5との違いや、確認ポイントを分かりやすくまとめて紹介します。
今回はLinuxの/devに存在する疑似デバイスファイルのrandomとurandomについて紹介します。
これらはその名の通り、乱数ジェネレーターを指す疑似デバイスファイルです。
この記事ではLinuxシステム上の乱数の生成方法として提供される/dev/randomと/dev/urandomの特徴と使い方を説明します。
加えて等価の処理として、Linux 3.17 (glibc 2.25.)で導入されたgetrandomシステムコールの使い方についてもサンプルプログラム を掲載して紹介します。
それでは行ってみます。
Linuxの/dev/randomや/dev/urandomはエントロピープールを利用した乱数ジェネレーターです。
エントロピープールとは、ハードウェア(キーボード・マウス・CPUなどの)動作から得られる環境ノイズを蓄積した データ領域のことを指します。
ハードウェアから発生する物理特性に基づいた不規則な環境ノイズを蓄積し、それを元に乱数を生成することで 推測が困難な真の乱数(※)の生成を実現しています。
/dev/randomや/dev/urandomは共に乱数ジェネレーターとして機能しますが、それぞれは異なる特性を持ちます。
/dev/randomは乱数の生成に使用した(中身を開示した)エントロピープールを再利用しないようにロックを掛けて 新しい環境ノイズが蓄積するのを待つ特性を持ちます。そのため、連続した乱数生成を実施できない場合があります。
対して、/dev/urandomは一度使用したエントロピープールを再利用してそれから乱数を生成することができる特性を持ちます。 そのため、いつでも使用することが可能代わりに疑似的な乱数を生成します。これにより、乱数の推測は/dev/randomよりも 容易になりますが、連続した乱数生成における制約はありません。
このように、/dev/randomと/dev/urandomは異なる特性(メリット・デメリット)を持った乱数ジェネレーターです。
次節では両者のメリット・デメリットをもう少しまとめて掲載した上で、その使い方を紹介します。
真の乱数と言ってもハードウェアから発生する環境ノイズを利用したものなので、外部から推測が可能な場合が常にあります。 そのため最大限、外部からの推測を困難にするような乱数の生成規則を適用する工夫が施されています。
エントロピープールを元に乱数を生成する疑似デバイスファイルです。
以下のメリットとデメリットを持ちます。
使い方は以下のようにして、/dev/randomから生成される乱数列をheadやodで利用したい分切り取ります。
kamo@kamo:~$ head -c 8 /dev/random | base64
kp9bxBY6osU=
kamo@kamo:~$ od -An -tu4 -N4 /dev/random | sed 's/^ *//'
6249257105
先に説明したように/dev/randomは一度使用すると、エントロピープールが再蓄積されるまでロックされます。
/dev/randomや/dev/urandomによって生成される乱数列はバイナリデータです。 そのため、英数字などのテキストデータに変換するためにBase64エンコードを実施する必要があります。
これによって、パスワードとして使用できる文字列(文字種:64個)を得ることができます。
※エンコードデータを元のバイナリデータに戻したい場合はBase64デコードをする必要があります。
エントロピープールを再利用する仕組みを持つため、/dev/randomのようにロックされることはありません。 常に開放(アンロック)されているのでurandomという名前が付けられています。
kamo@kamo:~$ head -c 8 /dev/urandom | base64
CXz43Q7aaUSK
kamo@kamo:~$ od -An -tu4 -N4 /dev/urandom | sed 's/^ *//'
1846207633
/dev/randomや/dev/urandomは疑似デバイスファイルであるため、使用するためにはファイルオープンをして ファイルディスクリプタ(fd)を割り当てないといけません。
つまり、ファイルディスクリプタの枯渇やchroot監獄の状態になるとファイルオープンが失敗しますので、 乱数生成することができなくなります。
そこで、LinuxではLinux 3.17、glibc 2.25からgetrandomシステムコールが導入されました。 getrandomシステムコールを利用することでファイルオープンに起因する乱数生成の失敗を回避することができます。 ※getrandomシステムコールの詳しい仕様はこちらを参照してください。
次にgetrandomシステムコールを使用したサンプルプログラム(random-generator.c)のソースコードを掲載します。
ここで紹介するソースコードは自由に使っていただいて構いません。 アプリケーションの開発や自己学習にお役立て下さい。ただし、当ブログでは掲載するソースコードを流用・利用したことによる損害等につきましては 一切の責任を負いません。自己責任で利用お願いします。
// random-generator.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/random.h> #define BUFFER_MAX_SIZE 256 void get_random_string(const char*, char*); char encode_base64(const char*, int); int main(void) { ssize_t result; char src[BUFFER_MAX_SIZE]; char dst[BUFFER_MAX_SIZE]; memset(src, '\0', BUFFER_MAX_SIZE); memset(dst, '\0', BUFFER_MAX_SIZE); // [FLAGS] // GRND_RANDOM ... source: /dev/random // GRND_NONBLOCK ... source: /dev/urandom (default) result = getrandom(src, BUFFER_MAX_SIZE, GRND_NONBLOCK); if (result == -1) { // check errno: https://man7.org/linux/man-pages/man3/errno.3.html perror("getrandom error"); return -1; } get_random_string(src, dst); fprintf(stdout, "The numbers of bytes that were copied to the \"buffer\": %d[bytes]\n", result); fprintf(stdout, "The random string (%d characters) : %s\n", strlen(dst), dst); return 0; } void get_random_string(const char* buf, char* dst) { int offset = sizeof(long); int cnt = 0; int i = 0; for (i = 0; (i < BUFFER_MAX_SIZE) && (cnt < BUFFER_MAX_SIZE); i += offset) { if ((i + offset) > BUFFER_MAX_SIZE) { return; } dst[cnt++] = encode_base64(buf, i); } } char encode_base64(const char* buf, int target_pos) { long num = 0L; char* encode_character = NULL; int long_byte_size = sizeof(long); int shiftcnt; for (shiftcnt = long_byte_size - 1; shiftcnt > 0; shiftcnt--) { num |= (long)buf[target_pos++] >> (shiftcnt * 8); } num |= (long)buf[target_pos]; encode_character = l64a(num); return *encode_character; }
今回使用しているbase64エンコード関数はl64aです。
この関数は引数のlong型データをbase64エンコードの一種に変換する処理です。 厳密なbase64エンコードではないため、変換される文字セットの範囲が若干異なります。
l64a関数の変換文字セットの詳細はこちらを参照してください。
ポイント
getrandomは第三引数として、以下のいずれかのフラグ(マクロ定数)を指定することで乱数生成のソースを
/dev/randomとするのか/dev/urandomとするのかを選択します。
| フラグ | 説明 |
|---|---|
| GRND_RANDOM | 乱数生成のソースとして/dev/randomを使用する |
| GRND_NONBLOCK | 乱数生成のソースとして/dev/urandomを使用する |
上記サンプルプログラムの実行結果は以下のようになります。
kamo@kamo:~$ gcc -o random-generator random-generator.c kamo@kamo:~$ ./random-generator The numbers of bytes that were copied to the "buf": 256[bytes] The random string (64 characters) : MCR7bRWdVFvudPyY12C4dbL9SYgiKIqRFL6iwTSxhwG7DeGtt6qVZZKLJc7SCtah
今回はLinuxシステム上で使用できる乱数ジェネレーターとして/dev/randomと/dev/urandom(それとgetrandom)について 紹介しました。
これらはLinux上のアプリケーション開発でデータの暗号化やパスワードを提供する場面などで利用できます。
メリットとデメリットを考慮して利用することをお勧めします。
USB4とは何か? パソコン購入前に知っておきたいポイントを整理
USB4とは何かを、パソコン購入前に知っておきたい人向けに整理します。Thunderbolt 4 / 5との違いや、確認ポイントを分かりやすくまとめて紹介します。
3Dプリンターの選び方! 造形方式や素材、確認ポイントを整理して紹介
3Dプリンターの選び方を紹介します。FDMと光造形の違い、PLAやPETG、ABSなどの素材、造形サイズ、家庭で使うときの注意点、代表的なメーカーと製品を整理しています。
2026年版 アクションカメラおすすめの選び方 初心者向けに主要メー カーを比較
アクションカメラの選び方を初心者向けに解説。4K、手ブレ補正、防水、バッテリー、GoPro・DJI・Insta360・AKASOの代表モデルを紹介します。
初心者向けノートパソコンおすすめ10選 失敗しにくい選び方を整理
ノートパソコンを初めて選ぶ人向けに、比較しやすい10機種を紹介します。メモリ、ストレージ、画面サイズ、重さ、Office有無、保証の見方を整理します。
レーザー彫刻機の選び方を紹介! 家庭向けで見たい方式や確認ポイントを整理
今回はレーザー彫刻機の選び方を紹介します。ダイオード、CO2、ファイバーの違い、家庭用で最初に見たい確認ポイント、代表的な メーカーと製品、家庭で使うときの注意点を整理して紹介します。
Thunderboltとは何か? パソコン購入前に知っておきたいポイントを整理
Thunderboltとは何かを、パソコン購入を検討している人向けに整理します。Thunderbolt 4と5の違い、USB4との関係、製品ページで確認したいポイントをまとめています。