2014-10-18 1 views
7

General purpose random number generation에 의해 영감을 받았습니다. rand()에서 잘못된 점을보기 위해 자체 테스트를 수행하기로 결정했습니다. 이 프로그램을 사용 :rand()는 실제로 그렇게 나쁜가요?

srand(time(0)); 
for (int i = 0; i < 1000000; ++i) 
{ 
    std::cout << rand() % 1000 << " "; 
} 

는 내가 명령을 사용하여 옥타브에 그것을로드 :

S = load("test.txt") 
hist(S) 

을 그리고이 결과를 가지고 : 결과가 꽤 것 같다 나에게

result

을 제복. 나는 결과가 더 비뚤어 질 것으로 예상했다. 나는 시험을 잘못 했습니까?

+2

rand는 주로 다음과 같은 이유로 좋지 않습니다.'RAND_MAX'는 구현이 정의되어 있으며, 예를 들어 Visual Studio에서는 단지 2^16입니다. rand는 전역 적입니다. 즉, 다른 사람이 srand를 호출하면 코드가 엉망이 될 수 있습니다. C++ 11- 컴파일러 컴파일러를 사용하는 경우, RNG 중 하나를 사용하는 것을 고려하십시오. – Creris

+0

구현에 따라'rand()'는 하위 비트에서 낮은 엔트로피를 가질 수 있습니다. 'rand() % 4'을했다면, 약간의 구현에서 이것은 꽤 비 균일합니다. 그래서이 경우'rand()/(RAND_MAX/4) '를 쓰는 것이 보통 ('rand()'를 사용한다면) 추천된다. – leemes

+6

* rand()가 실제로 그렇게 나쁜가요? * 예! –

답변

8

질문에 대한 테스트가 실제로 임의성을 테스트하지는 않습니다. 숫자가 균등하게 분배되도록하는 것뿐입니다. 이것은 필수적이지만 충분 조건은 아닙니다. 난수 생성기가 불충분 할 수있는 다른 많은 방법이 있습니다.

예를 들어 루프에 숫자 0, 1, 2, ..., 999를 반환 한 함수를 제공하면 테스트에도 합격하게됩니다. 그러나 그것은 임의성에 대한 합리적인 정의가 분명히 실패 할 것입니다.

rand() Considered Harmful을 확인, 특히 rand()의 설명은

에서 살펴보고, 실제로 테스트하는 방법을 난수 생성기 확인하려면 .

+0

http://xkcd.com/221/ EDIT : 두 번째 링크의 dilbert가 더 좋습니다. –

1

당신이 고려하지 않은 중요한 점은 생성 된 임의 순서가 얼마나 예측 가능한지입니다. randomness seed로 time()을 사용하는 경우, 공격자가 시드가 생성되었을 때 공격자가 알 수있는 것 - 많든 적든간에 -을 알면 그는 임의의 전체 시퀀스를 오히려 쉽게 재생할 수 있습니다.

보안과 관련된 모든 항목에이 난수를 사용한다고 가정 할 때 실제 무작위 소스가 필요한 이유입니다.

보안이 중요한 경우 PRNG에 전혀 의지하지 않고 진정한 무작위 소스에서 각 번호를 얻고 싶을 것입니다. 느리지 만 안전합니다.

0

귀하의 목적에 따라 제공되는 rand()은 배급 가능성이있는 손으로 사용하기에 간단하며 암호화 목적이나 물리적 시뮬레이션 목적으로 설계되지 않았습니다. 암호화 수준을 하나 또는 물리적 시뮬레이션을 원한다면 좋은 선택이 아니므로 특별한 구현을해야 할 수도 있습니다.
아직 컴퓨터 프로그램에서 생성 된 임의 번호는 입니다.

+1

마지막 문장과 관련하여 다음 기기를 제외시키고 있습니까? http://en.wikipedia.org/wiki/Hardware_random_number_generator? – NPE

+0

@NPE 귀하의 친절한 수정에 감사드립니다. –

관련 문제