「プロセスIDを擬似乱数生成関数の初期化パラメータに使う是非」の版間の差分
ナビゲーションに移動
検索に移動
編集の要約なし |
|||
(同じ利用者による、間の2版が非表示) | |||
5行目: | 5行目: | ||
<pre> | |||
#include <stdlib.h> | #include <stdlib.h> | ||
#include <stdio.h> | #include <stdio.h> | ||
#include <unistd.h> | #include <unistd.h> | ||
int main(void) | int main(void){ | ||
{ | |||
int i; | int i; | ||
srand((int)getpid()); | srand((int)getpid()); | ||
19行目: | 18行目: | ||
} | } | ||
} | } | ||
</pre> | |||
サンプルコードとして理解するのは良いでしょうが、このようなコードは実際のプログラムでは書くべきではありません。 | サンプルコードとして理解するのは良いでしょうが、このようなコードは実際のプログラムでは書くべきではありません。 | ||
理由はプロセスIDはある一定の数で循環している値であり、安全性を保つには変動の幅が小さく生成された擬似乱数のパターンが簡単に再現出来てしまうからです。 | 理由はプロセスIDはある一定の数で循環している値であり、安全性を保つには変動の幅が小さく生成された擬似乱数のパターンが簡単に再現出来てしまうからです。 | ||
カーネルが最少の構成で作られている場合、PIDの最大は4096よりも小さくなります。32ビットCPUの場合は32768です。 | |||
64ビットCPUの場合、カーネルのコードの中で最大は4 * 1024 * 1024つまり4194304と定義されています。 | |||
動いているカーネルで実際に取りうる最大の値は /proc/sys/kernel/pid_max で得られます。 | |||
筆者の64ビットCPUマシンでも4194304でした。逆をいえば、その程度の試行で見つけることができるということです。 | |||
さらにプログラムがブート時にこのようなプログラムが稼働してしまった場合、プロセスIDは毎回似たような値になります。 | さらにプログラムがブート時にこのようなプログラムが稼働してしまった場合、プロセスIDは毎回似たような値になります。 | ||
Linux上で予見が困難である(擬似)乱数の列が欲しい場合、/dev/ | |||
Linux上で予見が困難である(擬似)乱数の列が欲しい場合、/dev/urandomを使うなど工夫が必要です。 |
2022年2月17日 (木) 04:51時点における最新版
プロセスIDを擬似乱数生成関数の初期化パラメータに使うと何が起こるか
よく下のような擬似乱数生成関数の初期化で与えるパラメータ(SEED)の値をプロセスIDにするサンプルコードを見かけます。
#include <stdlib.h> #include <stdio.h> #include <unistd.h> int main(void){ int i; srand((int)getpid()); printf("PID %d\n", getpid()); for (i = 0; i < 5; i++) { printf("%d: random %d\n", i, rand()); } }
サンプルコードとして理解するのは良いでしょうが、このようなコードは実際のプログラムでは書くべきではありません。
理由はプロセスIDはある一定の数で循環している値であり、安全性を保つには変動の幅が小さく生成された擬似乱数のパターンが簡単に再現出来てしまうからです。
カーネルが最少の構成で作られている場合、PIDの最大は4096よりも小さくなります。32ビットCPUの場合は32768です。
64ビットCPUの場合、カーネルのコードの中で最大は4 * 1024 * 1024つまり4194304と定義されています。
動いているカーネルで実際に取りうる最大の値は /proc/sys/kernel/pid_max で得られます。
筆者の64ビットCPUマシンでも4194304でした。逆をいえば、その程度の試行で見つけることができるということです。
さらにプログラムがブート時にこのようなプログラムが稼働してしまった場合、プロセスIDは毎回似たような値になります。
Linux上で予見が困難である(擬似)乱数の列が欲しい場合、/dev/urandomを使うなど工夫が必要です。