【C#初級者向け解説】C#を使って乱数を生成する方法
ここではゲームプログラミングなどでよく使われる「乱数」の概要と生成方法について紹介します。
- プログラマー
- そもそも乱数って何ですか?
- プロジェクト
リーダー - ランダムとも呼ばれますね。ゲームなどで不規則に数字などを抽出したりする時に役立ちます。C#ではRandomクラスも準備されているので、プログラマーはこのクラスを用いて乱数を表現することになります。
C#で使用される乱数の概要
C#には擬似乱数が準備されています。
擬似乱数というのは、結果が読めるタイプの乱数であり、乱数を作成するRandomクラスにシードと呼ばれる値を渡します。
このシード値がとても大切な要素です。定数をシード値に設定してクラスに渡してしまうと同じ値が返ってしまうので、常に変化する時刻などをシード値にしてクラスに渡します。
使い方を間違えてしまうと毎回同じ値が返ってくるため注意が必要です。
擬似乱数はある特定の規則や数式を使って乱数を表現しています。
そのため、ランダムのように見えているだけで厳密にはランダムではなく、規則性のある数字または文字の羅列になります。
このため暗号化などに使用する場合は、RNGCryptoServiceProviderクラスが使用されることもあります。
C#の乱数の生成方法
C#で擬似乱数を表現するには、Randomクラスを利用します。
Randomクラスを用いる時には注意が必要であり、引数なしのコンストラクタを使用した場合はシード値にEnvironmentクラスのTick Countプロパティが設定されます。
このTick Countプロパティは、PCを最後に起動してからの経過時間をミリ秒単位で返します。その為、ループ処理の中で連続して複数のRandomクラスのインスタンスを作成した場合、シード値が同じ状態でインスタンスを作成する可能性があります。
以下、コーディングの良い例と悪い例です。
コーティングとして悪い例:コンストラクタに引数を指定しないでインスタンスを作成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class NG
{
static void Main()
{
for (int i = 0; i < 50; i++)
{
//コンストラクタに引数を指定しないでインスタンスを作成
Random rnd = new Random();
for (int j = 0; j < 10; j++)
{
Console.Write("{0} ", rnd.Next(10, 100));
}
}//for(i)文の終わり
}
}
|
コーディングとして良い例:シード値を変えながらRandomクラスのインスタンスを作成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public class OK
{
static void Main()
{
int seed = Environment.TickCount;
for (int i = 0; i < 50; i++)
{
//シート値を変えながらRandomクラスのインスタンスを作成する
Random rnd = new Random(seed++);
for (int j = 0; j < 10; j++)
{
Console.Write("{0} ", rnd.Next(10, 100));
}
}//for(i)文の終わり
}
}
|
擬似乱数ではなく、暗号化などでより厳密な乱数を使用する場合は、RNGCryptoServiceProviderクラスを利用すると良いでしょう。シード値の作成も厳密に行ってくれるので、Randomクラスのような現象は発生しません。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
using System;
using System.Security.Cryptography;
class Test {
static void Main()
{
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) {
byte[] nonce = new byte[16];
rng.GetBytes(nonce);
Console.WriteLine(BitConverter.ToString(nonce));
}
}
}
|
- プログラマー
- 簡単に使用できるRandomクラスって本当の意味でのランダムではなかったのですね……
- プロジェクト
リーダー - そうです。しかし、普通の人は擬似乱数の規則性に気付くことなんてありません。コーディングの仕方さえ間違えなければ、基本的にRandomクラスで生成する乱数表現をまず覚えておけばいいと思いますよ。
暗号化に擬似乱数を使用するのは控えましょう
C#を使って暗号化などで乱数を生成する場合はRNGCryptoServiceProviderクラスを利用する方が良いでしょう。
職場によっては擬似乱数使用禁止にしていることも考えられるため、この機会にぜひ覚えておくことをおすすめします。
FEnet.NETナビ・.NETコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。
-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社オープンアップグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。
新着案件New Job
-
開発エンジニア/東京都品川区/【WEB面談可】/在宅ワーク
月給29万~30万円東京都品川区(大崎駅) -
遠隔テストサービス機能改修/JavaScript/東京都港区/【WEB面談可】/テレワーク
月給45万~60万円東京都港区(六本木駅) -
病院内システムの不具合対応、保守/東京都豊島区/【WEB面談可】/テレワーク
月給30万~30万円東京都豊島区(池袋駅) -
開発/JavaScript/東京都豊島区/【WEB面談可】/テレワーク
月給50万~50万円東京都豊島区(大塚駅) -
債権債務システム追加開発/東京都文京区/【WEB面談可】/在宅勤務
月給62万~67万円東京都文京区(後楽園駅) -
PMO/東京都豊島区/【WEB面談可】/在宅勤務
月給55万~55万円東京都豊島区(池袋駅)