「プロセスIDを擬似乱数生成関数の初期化パラメータに使う是非」の版間の差分

提供:UnixClassWiki
ナビゲーションに移動 検索に移動
編集の要約なし
 
(同じ利用者による、間の2版が非表示)
5行目: 5行目:




<syntaxhighlight lang="C" line>
<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>


</syntaxhighlight>


サンプルコードとして理解するのは良いでしょうが、このようなコードは実際のプログラムでは書くべきではありません。
サンプルコードとして理解するのは良いでしょうが、このようなコードは実際のプログラムでは書くべきではありません。
理由はプロセスIDはある一定の数で循環している値であり、安全性を保つには変動の幅が小さく生成された擬似乱数のパターンが簡単に再現出来てしまうからです。
理由はプロセスIDはある一定の数で循環している値であり、安全性を保つには変動の幅が小さく生成された擬似乱数のパターンが簡単に再現出来てしまうからです。
カーネルが最少の構成で作られている場合、PIDの最大は4096よりも小さくなります。32ビットCPUの場合は32768です。64ビットCPUの場合に始めて最大2の30乗という値を取ることが出来ますが、動いているカーネルで実際に取りうる最大の値は /proc/sys/kernel/pid_max で得られます。ちなみに筆者の64ビットCPUマシンでは4194304でした。逆をいえば、その程度の試行で見つけることができるということです。
カーネルが最少の構成で作られている場合、PIDの最大は4096よりも小さくなります。32ビットCPUの場合は32768です。
64ビットCPUの場合、カーネルのコードの中で最大は4 * 1024 * 1024つまり4194304と定義されています。
動いているカーネルで実際に取りうる最大の値は /proc/sys/kernel/pid_max で得られます。
筆者の64ビットCPUマシンでも4194304でした。逆をいえば、その程度の試行で見つけることができるということです。
さらにプログラムがブート時にこのようなプログラムが稼働してしまった場合、プロセスIDは毎回似たような値になります。
さらにプログラムがブート時にこのようなプログラムが稼働してしまった場合、プロセスIDは毎回似たような値になります。


Linux上で予見が困難である(擬似)乱数の列が欲しい場合、/dev/randomを使うなど工夫が必要です。
 
 
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を使うなど工夫が必要です。