乱数

じゃんけん パー!(Reload してね)

ソース

<?php
  $janken[0] = "グー"; $janken[1] = "チョキ"; $janken[2] = "パー";
  $r = (microtime() * 1000000) % 3;
  echo $janken[$r];
?>

解説

乱数とはでたらめな数のことです。

ここでは乱数といっても単に時刻から得られる値を3で割って,余りが0なら「グー」,1なら「チョキ」,2なら「パー」としているだけです。

microtime() が1970年の元旦からの秒数を文字列として返す関数です。文字列はスペースで区切られて,前半はマイクロ秒,後半は秒の値になっています。例えば現在の microtime() は 0.13075700 1711701740 です。

通常の計算で使うと,前半の部分だけが使われますので,1000000(百万)を掛けて整数に直し,それを3で割った余りを $r に代入しています。

配列 $janken[0〜2] を作り,それで「グー」「チョキ」「パー」を表しています。

課題

「グー」「チョキ」「パー」だけでなく背景の色も変わります。これはどうしているのでしょうか。

もっと乱数

PHP には a 以上 b 以下の乱数を返す関数 rand(a, b) があります。これは乱数を初期化する関数 srand(x) を最初に呼び出してから使います。srand(x) に与える整数 x によって乱数が決まります。これを使ったソース例を挙げておきます。

<?php
  srand(microtime() * 1000000);
  $janken[0] = "グー"; $janken[1] = "チョキ"; $janken[2] = "パー";
  echo $janken[rand(0, 2)];
?>

もっと良い乱数として mt_rand(a, b) とそれを初期化する mt_srand(x) も PHP に備わっています。これは Mersenne Twister を使うものです。

ただ,良い乱数の良さは多数回使わないとわかりません。今回のように1回きりのものは,初期化の手順だけしか意味がありません。

暗号学的に安全な乱数

PHP 7 以降には random_bytes という暗号学的に安全なバイト列を生成する関数が備わっています(それ以前の PHP には random_compat を併用します)。例えば

<?php
  echo base64_encode(random_bytes(6));
?>

とすると,6バイトのランダムなバイト列を生成し,それをBASE64に直して,例えば

T/1MowRO

のように出力します。