본문 바로가기
C#

[C#] Random & RandomNumberGenerator

by DANEW 2023. 8. 20.

Random & RandomNumberGenerator 

 

Random 클래스 (System)

의사(pseudo) 난수 생성기를 나타냅니다. 이 알고리즘은 무작위성에 대한 통계적인 특정 요구 사항과 일치하는 숫자 시퀀스를 생성합니다.

learn.microsoft.com

- byte, int, double 형식의 난수들로 이루어진 의사난수열(Pseudorandom Sequence)를 생성

- 보안 요구 수준이 높은 응용에 적합할 정도로 무작위한 것은 아님.

 

- 같은 종잣값(seed)를 사용하면 같은 난수열이 나옴. 재현성(Reproducibility)

- 종잣값을 지정하지 않으면 현재 시스템 시간을 이용해서 만듬

 * 시스템 클록의 해상도가 그렇게 세밀하지 않기에 Random 인스턴스를 연속해서 생성하면 같은 난수열이 만들어질 위험이 존재함

 * 가능하면 하나의 인스턴스를 재사용, 단, 이런 방식은 스레드에 안전하지 않음

 

- Next(n): 0에서 n-1 사이의 난수 생성

- NextDouble: 0 이상 1 미만 double 형식 난수 생성

- NextBytes: 바이트 배열에 무작위한 값 채워 넣기

 

 

RandomNumberGenerator 클래스 (System.Security.Cryptography)

임의 값을 생성하는 기능을 제공합니다.

learn.microsoft.com

- 암호학적으로 강한 난수 발생기

- 바이트 배열로만 난수를 얻을 수 있기 때문에 유연성이 떨어짐

 * 다른 자료형의 난수를 얻기 위해선 BitConverter를 사용해야 함

반응형
using System;
 
namespace Practice
{
    class Program
    {
        static void Main(string[] args)
        {
            // 같은 시드 값
            Random r1 = new Random(1);
            Random r2 = new Random(1);
 
            Console.Write("r1".PadLeft(5));
            Console.Write("r2".PadLeft(5));
            Console.WriteLine();
            for (int i = 0; i < 10; i++)
            {
                Console.Write(r1.Next(100).ToString().PadLeft(5));
                Console.Write(r2.Next(100).ToString().PadLeft(5));
                Console.WriteLine();
            }
            Console.WriteLine();
 
 
            // 현재 시간을 가지고 랜덤을 진행하나
            // 시스템 클록의 해상도가 같이 때문에 같은 시드값을 사용한다
            r1 = new Random();
            r2 = new Random();
 
            Console.Write("r1".PadLeft(5));
            Console.Write("r2".PadLeft(5));
            Console.WriteLine();
            for (int i = 0; i < 10; i++)
            {
                Console.Write(r1.NextDouble().ToString("F2").PadLeft(5));
                Console.Write(r2.NextDouble().ToString("F2").PadLeft(5));
                Console.WriteLine();
            }
            Console.WriteLine();
 
 
            // 바이트 채워넣기
            // 역시 마찬가지로 시드가 같기 때문에 같은 값이 나온다
            byte[] r1b = new byte[32];
            byte[] r2b = new byte[32];
            r1.NextBytes(r1b);
            r2.NextBytes(r2b);
           
           
            Console.Write("r1b: ");
            foreach (var item in r1b)
            {
                Console.Write(item.ToString("X2"));
            }
            Console.WriteLine();
 
            Console.Write("r2b: ");
            foreach (var item in r2b)
            {
                Console.Write(item.ToString("X2"));
            }
            Console.WriteLine();
 
 
 
            // 암호학적으로 강한 RandomNumberGenerator
            var rng = System.Security.Cryptography.RandomNumberGenerator.Create();
            rng.GetBytes(r1b);
            Console.Write("RNG: ");
            foreach (var item in r1b)
            {
                Console.Write(item.ToString("X2"));
            }
            Console.WriteLine('\n');
 
           
            // RNG를 통해 정수 난수 얻기
            byte[] intByte = new byte[4];
            rng.GetBytes(intByte);
            int result = BitConverter.ToInt32(intByte, 0);
            Console.Write("byte: ");
            foreach (var item in intByte)
            {
                Console.Write(item.ToString("X2"));
            }
            Console.WriteLine();
            Console.WriteLine("int: {0}", result);
        }        
    }
}

 

 

 

반응형

'C#' 카테고리의 다른 글

[C#] Guid  (0) 2023.08.24
[C#] Math  (1) 2023.08.23
[C#] Tuple  (1) 2023.08.22
[C#] 열거형과 System.Enum  (1) 2023.08.21
[C#] Complex  (1) 2023.08.19
[C#] BigInteger  (1) 2023.08.18
[C#] BitConverter  (1) 2023.08.17
[C#] XmlConvert  (1) 2023.08.16