「乱数」の版間の差分
| 行1: | 行1: | ||
| − | [[乱数]] (random number)とは、ランダムな数列である[[乱数列]] | + | [[乱数]] (random number)とは、ランダムな数列である[[乱数列]]の各要素のことです。C言語などでは、rand()関数を呼び出すことで乱数を得られます。[[OpenSSL]]コマンドで乱数データを生成したり、Unixでは、デバイスファイル random/urandom を読み出すことでも乱数データを得られます。 |
'''読み方''' | '''読み方''' | ||
| 行15: | 行15: | ||
* C++言語では、標準関数 rand() 関数を用いて乱数を生成できます。 | * C++言語では、標準関数 rand() 関数を用いて乱数を生成できます。 | ||
* UNIXでは、/dev/random, /dev/urandom のデバイスを読むこと乱数を得られます。 | * UNIXでは、/dev/random, /dev/urandom のデバイスを読むこと乱数を得られます。 | ||
| − | * [[OpenSSL]]コマンドを使用して乱数を生成できます。<syntaxhighlight lang=" | + | * [[OpenSSL]]コマンドを使用して乱数を生成できます。 |
| − | + | === C言語 === | |
| + | ==== rand() ==== | ||
| + | <syntaxhighlight lang="c"> | ||
| + | /* | ||
| + | * rand.c | ||
| + | * Copyright (C) 2014 kaoru <kaoru@bsd> | ||
| + | */ | ||
| + | #include <stdio.h> | ||
| + | #include <stdlib.h> | ||
| + | #include <time.h> | ||
| + | |||
| + | int | ||
| + | main(int argc, char *argv[]) { | ||
| + | srand( time(NULL) ); | ||
| + | int r = rand (); | ||
| + | printf ("%d\n", r); | ||
| + | return 0; | ||
| + | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| + | ==== /dev/urandom ==== | ||
| + | /dev/urandomを/dev/randomに変更すれば、/dev/randomから読み出します。 | ||
| + | <syntaxhighlight lang="c"> | ||
| + | #include <stdio.h> | ||
| + | #include <stdlib.h> | ||
| + | #include <stdarg.h> | ||
| + | #include <err.h> | ||
| + | #include <errno.h> | ||
| + | #include <unistd.h> | ||
| + | #include <sys/types.h> | ||
| + | #include <fcntl.h> | ||
| + | |||
| + | #define DEV_RANDOM "/dev/urandom" | ||
| + | #define BUF 256 | ||
| + | |||
| + | int | ||
| + | get_random (char * const buf, const int buflen, const int len) | ||
| + | { | ||
| + | if (len > buflen) | ||
| + | { | ||
| + | warnx ("buffer size is small (%d / %d)", buflen, len); | ||
| + | return (-1); | ||
| + | } | ||
| + | int fd = open(DEV_RANDOM, O_RDONLY); | ||
| + | if (fd == -1) | ||
| + | { | ||
| + | warn ("can not open %s", DEV_RANDOM); | ||
| + | return (-1); | ||
| + | } | ||
| + | int r = read (fd, buf, len); | ||
| + | if (r < 0) { | ||
| + | warn ("can not read"); | ||
| + | return (-1); | ||
| + | } | ||
| + | if (r != len) | ||
| + | { | ||
| + | warnx ("can not read(%d != %d)", r, len); | ||
| + | return (-1); | ||
| + | } | ||
| + | |||
| + | (void) close (fd); | ||
| + | return (0); | ||
| + | } | ||
| + | </syntaxhighlight> | ||
| + | === PHP === | ||
| + | ==== mt_rand ==== | ||
| + | rand()ではなく、mt_rand()を使用します。mt_rand()は、乱数生成器 Mersenne Twister を使用します。平均してlibcのrand()よりも4倍以上高速に乱数を生成できます。 | ||
| + | srand()は、seedが必要でしたが、PHP4.2.0以降は、ランダム数生成器にシードが与える必要がなくなりました。 | ||
| + | <syntaxhighlight lang="php"> | ||
| + | <?php | ||
| + | mt_srand(); | ||
| + | echo mt_rand() , PHP_EOL; | ||
| + | ?> | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | 5から15まで(両端を含む)の[[乱数]]を得るには、範囲を指定します。 | ||
| + | <syntaxhighlight lang="php"> | ||
| + | <?php | ||
| + | echo mt_rand(5, 15), PHP_EOL; | ||
| + | ?> | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | レガシーな rand()のコードは、以下の通りです。 | ||
| + | <syntaxhighlight lang="php"> | ||
| + | <?php | ||
| + | srand(); | ||
| + | echo rand() , PHP_EOL; | ||
| + | echo rand(5, 15), PHP_EOL; | ||
| + | ?> | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | [[暗号]]のために安全な乱数データが欲しい場合には、openssl_random_pseudo_bytes()を使用します。PHPのopensslモジュールが必要になります。 | ||
| + | |||
| + | 10バイトの乱数が得たい場合、以下のコードになります。 | ||
| + | <syntaxhighlight lang="php"> | ||
| + | <?php | ||
| + | $data = openssl_random_pseudo_bytes(10); | ||
| + | ?> | ||
| + | </syntaxhighlight> | ||
| + | openssl_random_pseudo_bytes()は、バイト列を返すので、画面にエコーしたいなら16進数にします。 | ||
| + | <syntaxhighlight lang="php"> | ||
| + | <?php | ||
| + | /** | ||
| + | * Short description for openssl_random_pseudo_bytes.php | ||
| + | * | ||
| + | * @package openssl_random_pseudo_bytes | ||
| + | * @author kaoru <kaoru@bsd> | ||
| + | * @copyright (C) 2014 kaoru <kaoru@bsd> | ||
| + | */ | ||
| + | $data = openssl_random_pseudo_bytes(20); | ||
| + | echo bin2hex($data),PHP_EOL; | ||
| + | ?> | ||
| + | </syntaxhighlight> | ||
| + | 上記のコードを実行すると、このようになります。 | ||
| + | <syntaxhighlight lang="bash"> | ||
| + | $ php openssl_random_pseudo_bytes.php | ||
| + | b5b9801a5f00cd0f322e59268169982867a944ed | ||
| + | </syntaxhighlight> | ||
| + | === OpenSSL コマンドによる乱数データの生成 === | ||
| + | [[OpenSSL]]コマンドを用いて、100バイトのデータを生成する例です。 | ||
| + | <syntaxhighlight lang="bash"> | ||
| + | openssl rand 100 -out /tmp/rand.100 | ||
| + | </syntaxhighlight> | ||
| + | === dd コマンドとrandomデバイスによる乱数データの生成 === | ||
| + | 1MBのファイルを作成する例です。 | ||
| + | <syntaxhighlight lang="bash"> | ||
| + | $ dd if=/dev/random of=urandom.dat count=1024 bs=1024 | ||
| + | </syntaxhighlight> | ||
| + | urandomの場合は、/dev/urandomを指定します。 | ||
| + | <syntaxhighlight lang="bash"> | ||
| + | $ dd if=/dev/urandom of=urandom.dat count=1024 bs=1024 | ||
| + | </syntaxhighlight> | ||
== 関連項目 == | == 関連項目 == | ||
* [[擬似乱数]] | * [[擬似乱数]] | ||
2014年11月26日 (水) 00:08時点における版
乱数 (random number)とは、ランダムな数列である乱数列の各要素のことです。C言語などでは、rand()関数を呼び出すことで乱数を得られます。OpenSSLコマンドで乱数データを生成したり、Unixでは、デバイスファイル random/urandom を読み出すことでも乱数データを得られます。
読み方
- 乱数
- らんすう
- random number
- らんだむ なんばー
目次
概要
乱数とは、出現する値に規則性のない数です。 コンピューターでは、必要な範囲内で乱数とみなす擬似乱数を用います。
プログラミングにおける乱数
- C言語では、標準関数 rand() 関数を用いて乱数を生成できます。
- C++言語では、標準関数 rand() 関数を用いて乱数を生成できます。
- UNIXでは、/dev/random, /dev/urandom のデバイスを読むこと乱数を得られます。
- OpenSSLコマンドを使用して乱数を生成できます。
C言語
rand()
/* * rand.c * Copyright (C) 2014 kaoru <kaoru@bsd> */ #include <stdio.h> #include <stdlib.h> #include <time.h> int main(int argc, char *argv[]) { srand( time(NULL) ); int r = rand (); printf ("%d\n", r); return 0; }
/dev/urandom
/dev/urandomを/dev/randomに変更すれば、/dev/randomから読み出します。
#include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <err.h> #include <errno.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #define DEV_RANDOM "/dev/urandom" #define BUF 256 int get_random (char * const buf, const int buflen, const int len) { if (len > buflen) { warnx ("buffer size is small (%d / %d)", buflen, len); return (-1); } int fd = open(DEV_RANDOM, O_RDONLY); if (fd == -1) { warn ("can not open %s", DEV_RANDOM); return (-1); } int r = read (fd, buf, len); if (r < 0) { warn ("can not read"); return (-1); } if (r != len) { warnx ("can not read(%d != %d)", r, len); return (-1); } (void) close (fd); return (0); }
PHP
mt_rand
rand()ではなく、mt_rand()を使用します。mt_rand()は、乱数生成器 Mersenne Twister を使用します。平均してlibcのrand()よりも4倍以上高速に乱数を生成できます。 srand()は、seedが必要でしたが、PHP4.2.0以降は、ランダム数生成器にシードが与える必要がなくなりました。
<?php mt_srand(); echo mt_rand() , PHP_EOL; ?>
5から15まで(両端を含む)の乱数を得るには、範囲を指定します。
<?php echo mt_rand(5, 15), PHP_EOL; ?>
レガシーな rand()のコードは、以下の通りです。
<?php srand(); echo rand() , PHP_EOL; echo rand(5, 15), PHP_EOL; ?>
暗号のために安全な乱数データが欲しい場合には、openssl_random_pseudo_bytes()を使用します。PHPのopensslモジュールが必要になります。
10バイトの乱数が得たい場合、以下のコードになります。
<?php $data = openssl_random_pseudo_bytes(10); ?>
openssl_random_pseudo_bytes()は、バイト列を返すので、画面にエコーしたいなら16進数にします。
<?php /** * Short description for openssl_random_pseudo_bytes.php * * @package openssl_random_pseudo_bytes * @author kaoru <kaoru@bsd> * @copyright (C) 2014 kaoru <kaoru@bsd> */ $data = openssl_random_pseudo_bytes(20); echo bin2hex($data),PHP_EOL; ?>
上記のコードを実行すると、このようになります。
$ php openssl_random_pseudo_bytes.php b5b9801a5f00cd0f322e59268169982867a944ed
OpenSSL コマンドによる乱数データの生成
OpenSSLコマンドを用いて、100バイトのデータを生成する例です。
openssl rand 100 -out /tmp/rand.100
dd コマンドとrandomデバイスによる乱数データの生成
1MBのファイルを作成する例です。
$ dd if=/dev/random of=urandom.dat count=1024 bs=1024
urandomの場合は、/dev/urandomを指定します。
$ dd if=/dev/urandom of=urandom.dat count=1024 bs=1024