C#에서 임의 클래스 시드

Syed Hassan Sabeeh Kazmi 2024년2월15일
  1. C#에서 임의 클래스를 시드하는 함수 만들기
  2. Random() 클래스를 사용하여 C#에서 무작위 클래스 시드
  3. Environment.TickCount 속성을 사용하여 C#의 임의 클래스 시드
  4. RNGCryptoServiceProvider 클래스를 사용하여 C#의 임의 클래스 시드
C#에서 임의 클래스 시드

이 자습서에서는 응용 프로그램에서 임의성을 달성하기 위해 C#에서 클래스를 시드하는 방법에 대해 설명합니다. 클래스를 시드하는 네 가지 기본 방법이 있으며 모두 Random 클래스로 시작하여 인스턴스를 초기화하고 Next() 메서드를 호출하여 특정 범위 없이 숫자를 생성하여 임의의 정수를 얻고 다음을 얻을 수 있습니다. NextDouble() 메서드를 사용하여 십진수.

처음부터 클래스를 작성할 수 있습니다. Random 클래스, Environment.TickCount 또는 RNGCryptoServerProvider 클래스를 사용하여 C#에서 무작위 클래스를 시드할 수 있습니다.

C#에서 임의 클래스를 시드하는 함수 만들기

public static int random_func(int _min, int _max){}와 같은 함수를 생성하고 Random 클래스에서 객체를 생성하여 minmax 값에 대해 Next() 메서드를 수행합니다.

Random 클래스에서 개인용 정적 개체에 대한 작업을 수행하는 공용 함수를 보유하는 정적 클래스를 생성하여 이 기술을 반복할 수 있습니다. 진정한 상태 비저장 정적 메서드의 경우 Guid에 엄격하게 의존하여 Guid.NewGuid().GetHashCode()와 같은 난수를 생성할 수 있습니다.

using System;
using System.Windows.Forms;

namespace seed_random_class {
  public partial class Form1 : Form {
    // function to get a random number
    public static int RandomNumber(int min, int max) {
      Random random = new Random();
      return random.Next(min, max);
    }
    public Form1() {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e) {}

    private void label1_Click(object sender, EventArgs e) {}

    private void button1_Click(object sender, EventArgs e) {
      int min = 0;
      int max = 10;
      int return_num;
      return_num = Form1.RandomNumber(min, max);
      label1.Text = return_num.ToString();

      /* alternative approach

      byte[] _random = new byte[6];
      for (int i = 0; i < 6; ++i)
      _random[i] = (byte)(Form1.RandomNumber((int)0xFFFF, (int)0xFFFFFF) % 256);

      */
    }
  }
}

출력:

임의 클래스를 시드하는 함수 만들기

Guid 목표는 균일하게 분포되지 않고 고유해야 하며 대부분의 경우 무작위성과 반대일 수 있으며 균일한 분포를 구현하지 않으므로 Random 클래스를 기반으로 함수를 만드는 것이 유효한 접근 방식이라는 점을 이해하는 것이 중요합니다. . 또한 Random((int)DateTime.Now.Ticks)과 같이 예측할 수 없는 더 큰 숫자로 임의 클래스를 시드하여 더 나은 임의성을 얻을 수 있습니다.

Random() 클래스를 사용하여 C#에서 무작위 클래스 시드

Random 클래스의 인스턴스를 만들고 루프에서 해당 인스턴스에 Next() 메서드를 적용하는 것이 항상 C#에서 클래스를 시드하는 가장 좋은 방법입니다. 단일 Random 클래스 인스턴스가 생성하는 숫자는 항상 균일하게 분포되며 모든 난수에 대해 새 Random 클래스 인스턴스를 빠르게 연속적으로 생성하여 동일한 값으로 시드하여 동일한 난수를 생성할 수 있습니다.

완전성을 위해 Random 클래스를 다시 시드하고 새 시드에서 새 인스턴스를 생성하는 것이 좋습니다. 다시 시드하는 것은 예측 가능성이 문제가 될 때 더 좋은 임의 생성기를 사용하는 것과는 별개로 훌륭한 옵션입니다. 공격자 측에서 패턴 인식을 적용할 수 있는 것보다 빠르게 다시 시드해야 하며 동일한 값으로 2개의 생성기가 시드되지 않도록 할 수 있습니다.

new Random()은 항상 시스템 클록을 사용하여 초기화되므로 동일한 값을 얻을 수 있습니다. 따라서 단일 Random 인스턴스를 유지하고 동일한 인스턴스에서 Next() 메서드를 계속 사용해야 합니다.

using System;
using System.Windows.Forms;

namespace seed_random_class {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e) {}

    private void label1_Click(object sender, EventArgs e) {}

    private void button1_Click(object sender, EventArgs e) {
      var _random = new Random();
      for (int i = 0; i < 100; ++i) label1.Text = _random.Next(1, 100).ToString();
    }
  }
}

출력:

Random() 클래스를 사용하여 임의 클래스 시드

가장 중요한 것은 시드를 Next()와 동기화하려면 잠금이 필요합니다. 왜냐하면 Next()를 여러 스레드에 동시에 적용하면 결과를 훨씬 더 무작위로 만들 수 있기 때문입니다. 잠재적으로 내부 구현을 중단합니다. 잠금은 스레드 안전을 보장하며 동기화는 최대 임의성을 달성하는 가장 좋은 방법입니다.

Random 클래스 인스턴스와 함께 lock을 사용하는 것은 대안이지만 다른 것보다 덜 스레드 안전합니다. Random 개체의 스레드 및 매개 변수 없는 생성자를 사용한다고 가정합니다.

이 경우 Thread.Sleep 메서드 호출로 인해 지연이 발생하여 해당 개체에 대해 다른 시드 값을 생성하고 다른 순서의 난수를 생성할 수 있습니다.

Environment.TickCount 속성을 사용하여 C#의 임의 클래스 시드

이것은 System 네임스페이스에 속하며 시스템이 시작된 이후 밀리초 수를 가져오는 데 중요하며 32비트 부호 있는 정수를 나타냅니다. 이 속성은 각각 음수와 양수를 나타내는 Int32.MinValueInt32.MaxValue 사이를 순환하며 24.9일마다 한 번씩 0과 최대 양수 값 사이를 순환하는 음수가 아닌 숫자를 생성하기 위해 부호 비트를 제거할 수 있습니다. .

32비트 부호 있는 정수의 분해능은 10~16밀리초 범위의 시스템 타이머 분해능으로 제한됩니다. 가장 중요한 것은 System.Random에서 사용하는 구현이 Environment.TickCount이고 DateTime.UtcNow.Ticks를 캐스팅할 필요가 없으며 C# 애플리케이션 전체에서 무작위 클래스 시드 재사용을 쉽게 할 수 있다는 것입니다.

using System;
using System.Threading;  // essential namespace for threading
using System.Windows.Forms;

namespace seed_random_class {
  public static class StaticRandom {
    // initialize the seed
    private static int _var_seed;

    // a thread-safe approach to access the random class via seed
    // `<Random>` implies the Random class
    private static ThreadLocal<Random> local_thread =
        new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref _var_seed)));

    // method that utilizes the `Environment.TickCount` property
    static StaticRandom() {
      _var_seed = Environment.TickCount;
    }

    public static Random class_inst {
      get { return local_thread.Value; }
    }
  }
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e) {}

    private void label1_Click(object sender, EventArgs e) {}

    private void button1_Click(object sender, EventArgs e) {
      label1.Text = StaticRandom.class_inst.Next(1, 100).ToString();
    }
  }
}

출력:

Environment.TickCount 속성을 사용하여 임의 클래스 시드

RNGCryptoServiceProvider 클래스를 사용하여 C#의 임의 클래스 시드

일부 고유한 경우 RNGCryptoServerProver 클래스를 사용해야 합니다. System.Security.Cryptography 네임스페이스에 속하며 CSP(Cryptographic Service Provider)에서 제공하는 구현을 사용하여 암호화 RNG(Random Number Generator)를 구현하며 상속할 수 없습니다.

IDisposable 인터페이스를 구현하고 try/catch 블록에서 Dispose 메서드를 호출할 수 있으므로 직접 또는 간접적으로 폐기하는 것이 중요합니다. C#에서는 using 구문을 사용하여 폐기하여 임의 클래스에 대한 완벽한 시드를 만들 수 있습니다.

System.Security.Cryptography.RNGCryptoServiceProvider 클래스는 스레드로부터 안전하며 알려진 시드에서 값을 재생산하여 실제 요구 사항을 충족합니다. 그러나 두 개의 독립적인 값을 생성할 수 있는 함수를 만드는 것은 수학적으로 불가능하며 이는 또한 모든 암호화 체계가 완전히 안전하지 않으며 때로는 사용 비용이 너무 높을 수 있음을 의미합니다.

using System;
using System.Windows.Forms;

namespace seed_random_class {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e) {}

    private void label1_Click(object sender, EventArgs e) {}

    private void button1_Click(object sender, EventArgs e) {
      byte[] foo = { 0x32, 0x00, 0x1E, 0x00 };
      System.Security.Cryptography.RNGCryptoServiceProvider prov =
          new System.Security.Cryptography.RNGCryptoServiceProvider();
      prov.GetBytes(foo);
    }
  }
}

출력:

RNGCryptoServiceProvider 클래스를 사용하여 임의 클래스 시드

Next(int) 또는 Next(int min, int max) 메서드를 사용하여 범위 내 난수를 생성하거나 Next()NextBytes()를 사용하여 각각 임의의 정수 및 계열을 생성할 수 있습니다. 바이트 값. 생성자 오버로드를 통해 시드를 제공하거나 프레임워크에서 이를 처리합니다.

Random 클래스를 인스턴스화하는 것은 비용이 많이 드는 접근 방식이며 과도하게 사용하면 C# 애플리케이션의 성능이 저하될 수 있습니다. 대신 단일 Random 인스턴스를 인스턴스화하고 Next() 메서드를 여러 번 호출합니다. 암호화는 C#에서 임의 클래스를 시드하는 보다 안전하고 보호적인 접근 방식입니다.

Syed Hassan Sabeeh Kazmi avatar Syed Hassan Sabeeh Kazmi avatar

Hassan is a Software Engineer with a well-developed set of programming skills. He uses his knowledge and writing capabilities to produce interesting-to-read technical articles.

GitHub

관련 문장 - Csharp Math