프로그램/C# 2013. 3. 8. 01:44

C# 난수 생성 , rand Random

난수라는 것은 연속적이지 않는 수를 말하는 것으로 System네임스페이스의 Random클래스를 사용합니다. 구체적으로 설명하美? 먼자 Random클래스를 인스턴스로 만들고 Next메소드를 호출하는 방식을 추천합니다.

만약, 0~99까지 랜덤한 정수를 1개를 얻고자 싶다면,

Random rd = new Random(); 
int rNum = rd.Next(100); 

이후 Next메소드를 호출할 때마다 다른 수를 얻을 수 있고 NextDouble메소드를 사용하면 0.0~0.1사이의 double형 난수를 생성합니다.

 

그러나, Random 클래스를 사용시 주의해야할 점이 있습니다. 이는 컴퓨터로 난수를 생성하는 경우, 지정한 수치를 시드값으로 정하고 이를 기초로 특정연산을 통해 난수를 만들어갑니다. 이때문에 동일한 시드값을 사용한 경우 발생한 난수는 완전히 동일한 것으로 됩니다.

 

Random클래스의 이벤트핸들로를 사용하여 인스턴스를 만들면, 그 시드값에는 Environment클래스의 TickCount속성을 사용합니다. 이 속성은 PC를 마지막으로 실행하고 나서 지난 시간을 리턴합니다. 이 때문에 연속하고 여러개의 Random클래스 인스턴스를 만들면, 시드값이 동일한 인스턴스를 만들어버릴 수 있습니다. 여기서는 이러한 오류가 발생하지 않도록 처리한 예제입니다.

 

using System; 

public class RandomExam1 { 
 static void Main() { 
  for(int i=0; i<50; i++) { 
  Random rd = new Random(); 
  for(int j=0; j<10; j++) { 
    Console.Write("{0} ", rd.Next(10,100)); 
  } 
  Console.WriteLine(Environment.TickCount); 
  } 
 } 
} 

 

실행된 출력된 내용을 보면 다른 인스턴스임에도 불구하고 동일한 난수를 생성해버리는 것을 확인하실 수 있을 겁니다. 이와 같이 난수는 위에서도 이야기했듯히 문제의 소지가 있습니다.

이런 경우를 대비하여 시드값을 지정할 수 있는 버전으로 변경하여 다음과 같이 개선하였습니다.

 

using System; 

public class RandomExam2 { 
 static void Main() { 
  int seed = Environment.TickCount; 
  for(int i=0; i<50; i++) { 
  Random rd = new Random(seed++); 
  for(int j=0; j<10; j++) { 
    Console.Write("{0} ", rd.Next(10,100)); 
  } 
  Console.WriteLine(); 
  } 
 } 
} 

 

위 예제는 시드값을 1씩 늘리는 만큼 난수를 발생시키는 구조입니다.

 

만약 보다 상세한 난수를 생성하고 싶은 분들은 암호화를 사용하여 난수열을 만드는 형태로 System.Security.Cryptography네임스페이스의 RNGCryptoServiceProvider클래스를 사용하거나 RandomNumberGenerator클래스를 사용할 수 있습니다.

이 클래스의 GetBytes메소드나 GetNonZeroByte메소드를 사용하여 바이트배열 난수열을 발생시킵니다. 

byte[] r = new byte[100]; 
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider() 
rng.GetBytes(r); 

 

[출처] C# 난수 생성 방법|작성자 메모리얼  Writter by Youngil Kim, C#.NET Developer

 

'프로그램 > C#' 카테고리의 다른 글

C# 외부 프로그램 실행  (0) 2013.03.08
C# 폼 상속  (0) 2013.03.08
C# 폼스타일 , FormBorderStyle  (0) 2013.03.08
C# 접근 수정자  (0) 2013.03.08
C# 데이터 타입  (0) 2013.03.08