랜덤함수 라는게 있다.
그런데 랜덤함수는 원래 사실 전혀 랜덤하지 않다.
함수라는 것 자체가,
인위적으로 만든것이기에,
그 공식만 알아내면
다음값이 뭐가 나올지는 충분히 추론이 가능하다.
그래서,
정말 랜덤한 값이 필요한 곳에서는
랜덤함수 시드값으로
자연적으로 생기는 값을 사용한다고,
바람의 세기나 뭐그따위 것들을 말이다.ㅋ
예전에 OTP 프로토타입 만든다고,
1분마다 새로운 번호를 생성하기 위해 랜덤함수를 사용했었다.
그런데,
자바로 구축했던 OTP 인증해주는 서버하고,
IOS앱에서 랜덤함수값이 서로 달라서 알아보다가
자바와 objective-c에서 사용하는 랜덤함수가
공식은 같은데, 상수값이 다르다
는 것을 확인.
그래서 상수값이 작은 objective-c부분의 랜덤함수를
자바쪽에 구현해서 해결.
자바의 상수값을 objective-c에 적용하려면 overflow가 발생한다. ㅎ
1. 랜덤함수 기본 공식
Xn+1 = (aXn + c) % M
이 공식은 Linear Congruential Generator 공식이다.
(http://en.wikipedia.org/wiki/Linear_congruential_generator)
모든 언어라고 말하기는 그렇지만,
적어도 우리가 사용하는 언어의 대부분에서는
전부 이공식에 따라 랜덤함수를 만들었다.
언어들간의 랜덤함수 값이 다른건 a,c,M에 해당하는 상수값이 달라서 이다.
2. 언어별 LCG(Linear Congruential Generator) 상수값
대부분 상수값 자체를 크게 줘서 int의 범위를 초과하도록 overflow를 일으켜 그로 인해 얻어지는 쓰레기값을 사용하기도 한다.
3. Xn+1 = (aXn + c ) mod M (Apple CarbonLib)
Xn+1 = ( 16807 * Xn + 0 ) mod (2의 31승 -1)
= Xn * 16807 % (2의 31승 -1)
= Xn * 16807 & 0x7fffffff
4. rand() 함수의 값과
xn * 16807 & 0x7fffffff 의 결과값이 동일하게 나온다.
여기예제에서는 OTP로 쓰이기 위해
랜덤함수를 무조건 동일한 규칙에 의해 나오게 끔 해야되서,
seed 값에 16807을 곱했을 경우 그 값이
overflow가 나지 않도록 조건을 걸긴 했다.
결론적으로 하고 싶은말은.
랜덤함수에는 공식이 있다는것. ㅋ
댓글
댓글 쓰기