2013-05-17 3 views
0

Google에서 RNGCryptoServiceProvider를 검색하는 중 Max와 Min 사이의 범위를 제한하는 방법에 대한 예가 나와 있는데도 균등 분포를 유지합니다. Modulo 연산자를 사용하기 전에 때때로 이상한 값 (최대 값 이상)을 얻습니다. 어쨌든이 코드는 RNGCCryptoServiceProvider의 새로운 시드로 무작위로, 매번 메서드가 호출됩니다. 너희들은 어떻게 생각하니?난수 생성을위한이 방법이 얼마나 좋은가?

+0

전화 할 때마다 다시 시드하는 것이 좋습니다. – recursive

+0

좋아, 그럼 난 단지 rng에서 하나의 씨앗을 시작하겠습니까? –

답변

2

당신은 한 번 RNGCryptoServiceProvider 개체를 만들려면 다음 해당 개체를 재사용합니다 매번 새로운 난수를 원한다. 예를 들어, 객체를 GetRandom() 메소드에 전달하거나 클래스 수준 필드에 저장할 수 있습니다.

RNGCryptoServiceProvider 유형 자체는 좋은 숫자를 생성하므로 Random 개체를 만들고 시드를 전달할 필요가 없습니다. 이렇게하면 매우 적절한 분포를 얻을 수 있습니다.

public static int GetRandom(RNGCryptoServiceProvider rngProvider, int min, int max) 
{ 
    byte[] b = new byte[sizeof(UInt32)]; 
    rngProvider.GetBytes(b); 
    double d = BitConverter.ToUInt32(b, 0)/(double)UInt32.MaxValue; 
    return min + (int)((max - min) * d); 
} 
+0

고마워! 나는 이것을 밖으로 시험 할 것이다! –

+0

'max - min'가 너무 커서 int에 포함될 수없는 경우이 구현에 정수 오버플로가 있습니다. – mschwaig

5

일반 임의 생성기를 시드하기 위해 암호화 클래스 임의 생성기를 사용할 필요는 없습니다. (가장 약한 ...의 원칙에 의해) 그냥 무작위 발전기의 단일 인스턴스를 사용하고 재사용 :

private static Random rnd = new Random(); 

public static int GetRandom(int min, int max) { 
    return rnd.Next(min, max); 
} 
+0

흠, 나는 그것이 Random.Next()를 개선 할 수 있기를 바랬다. –

+2

표준 '랜덤'은 암호화를 위해 또는 오랜 기간 (예 : 온라인 포커 게임)이 필요한 경우에만 약합니다. 그렇지 않으면 그 벌금. –

+0

@MatthewWatson 좋아, 그럼 그걸 고수 할께. –

0

난수 생성기를 응용 프로그램에 한 번만 시드하는 것이 좋습니다. 난수 생성을위한 정적 클래스를 만드는 것이 좋습니다. 무작위 생성 객체는 정상적인 사용으로 균등하게 분배 할 수 있습니다. RNGCryptoServiceProvider를 사용하여 발전기를 파는 이점이 무엇인지 모르겠습니다. 나는 평소와 같이 시딩 방법으로 시간을 사용하는 것을 선호한다. 따라서 다음 코드는 제 제안입니다.

int randomNumber=Rand.get(min,max); 

public static class Rand 
{ 
    private static Random rnd; 
    static rand() 
    { 
     rand=new Random(DateTime.Now.Ticks); 
    } 
    public static int get(int min,int max) 
    { 
     return rnd.Next(min,max); 
    } 
} 
관련 문제