2010-01-27 2 views
9

.NET에서 Java가 사용하는 정확한 임의 화를 모방 할 수 있습니까? 시드가 있고 난수 생성시 C#과 Java에서 동일한 결과를 얻을 수 있기를 원합니다.C#/자바 번호 무작위 화

+0

얼마나 무작위입니까? ... 그냥 물어보십시오. –

+0

@Filip : 확률 론적 임의성을 원한다고 암시한다고 생각합니다. –

+0

당신이 맞을 것 같네요. –

답변

5

Java 구현을위한 java.util.Random 클래스의 소스 코드가 있다면 .NET으로 쉽게 이식 할 수 있습니다.

임의의 난수 생성기를 사용하는 두 응용 프로그램 (Java 및 .NET)이 필요한 경우 시스템 제공 버전이 결과로 동작을 변경하므로 두 플랫폼 모두에서 하나의 구현을 사용하는 것이 좋습니다. 업데이트. (Java 사양과 유사하게 PRNG의 동작을 정확하게 설명합니다.)

+0

알고리즘은 구현 세부 사항이 아니며 버전/구현간에 변경 될 가능성이 있습니다. ?IMO는 일관된 결과를 얻으려면 Java와 C# 모두에서 사용자 지정 알고리즘을 구현하는 것이 좋습니다. – dtb

+0

@dtb : 똑같은 생각을하고있었습니다. 테스트 목적으로 임시적인 것이면 충분합니다. 그렇지 않으면 네 자신을 구현해야합니다. –

+4

@dtb :이 알고리즘은 Java의 Random 클래스의 설명서에서 지정되므로 사양입니다. 구현 세부 사항은 변경 될 수 있지만 향후 버전에서는 실제 시퀀스가 ​​생성된다는 점을 매우 의심합니다. 전혀 그렇지 않다면 다른 클래스에 다른 PRNG를 추가 할 확률이 높습니다. 하지만 실제로 Java가 의도 한 범위와 성숙한 라이브러리가 의사 난수 생성에 실제로 도움이된다면 어쨌든 그렇게 될지는 의문입니다. – Joey

0

음, Random.java 소스 코드에서 알고리즘, 상수 등을 복사 할 수 있지만 임의 코드는 System.nanoTime을 사용합니다. 생성자에서 동일한 결과를 얻을 수 없습니다. java.util.Random의

공공 랜덤() { 에서

이 (++ seedUniquifier + System.nanoTime()); }

C#의 소스가 비슷한 것을 표시한다면별로 놀랍지 않을 것입니다.

편집 : 지적했듯이 입력 시드를 사용하는 생성자는 절대로 시간에 액세스하지 않습니다.

+2

그는 두 가지 모두에 대해 동일한 시드를 사용하므로 Java 구현의 기본 시드는 부적합합니다. –

+0

시드가없는 경우에만 Random()을 사용합니다 - 아무 것도 취하지 않고 TickCount 대신 시드를 사용하는'Environment.TickCount'와'Random (int32 num)'을 사용합니다. –

0

아마도 자신의 간단한 의사 난수 생성기를 구현하는 것이 합리적일까요? 당신이 완벽하게 통제 할 수 있고 같은 씨앗을 garauntee 할 수있는 그런 식으로 두 환경 모두에서 같은 결과를 얻을 수 있습니다. 아마도 다른 하나를 이식하는 것보다 조금 더 많은 작업이있을 것입니다.

1

암호로 보호되는 의사 난수 생성기가 필요하지 않다면 Mersenne twister으로 갈 것입니다. C# hereJava here의 소스 코드를 찾을 수 있습니다.

+1

그래도 문제가되지 않았습니다. 그리고 java.util.Random'은 암호화되어 있지 않기 때문에 안심할 수 있습니다. – Joey

+1

그것은 "Java가 사용하는 정확한 랜덤 화를 모방 한 것입니다." 불가능에 나는 * "나는 C#과 Java 모두에서 같은 결과를 얻을 수 있기를 바란다."*에 집중했다. –

-2

또 다른 옵션은 임의의 번호를 하나의 플랫폼에서 파일로 작성한 다음 해당 파일에서 두 플랫폼의 난수를로드하거나 random.org와 같은 서비스에서로드 할 수 있습니다.

5

소스 코드를 읽을 필요가 없습니다.

[Serializable] 
public class Random 
{ 
    public Random(UInt64 seed) 
    { 
     this.seed = (seed^0x5DEECE66DUL) & ((1UL << 48) - 1); 
    } 

    public int NextInt(int n) 
    { 
     if (n <= 0) throw new ArgumentException("n must be positive"); 

     if ((n & -n) == n) // i.e., n is a power of 2 
      return (int)((n * (long)Next(31)) >> 31); 

     long bits, val; 
     do 
     { 
      bits = Next(31); 
      val = bits % (UInt32) n; 
     } 
     while (bits - val + (n - 1) < 0); 

     return (int) val; 
    } 

    protected UInt32 Next(int bits) 
    { 
     seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1); 

     return (UInt32)(seed >> (48 - bits)); 
    } 

    private UInt64 seed; 
} 

예 : 두 플랫폼

Random rnd = new Random(42); 
Console.WriteLine(rnd.NextInt(10)); 
Console.WriteLine(rnd.NextInt(20)); 
Console.WriteLine(rnd.NextInt(30)); 
Console.WriteLine(rnd.NextInt(40)); 
Console.WriteLine(rnd.NextInt(50)); 

출력이 0, 3, 18, 4, 20가 식 여기 부분의 번역 한 라이너와 documentation for java.util.Random.

주어진다.