package main
import (
"fmt"
"math/rand"
)
type jump struct {
max int64
count int32
loop int64
}
func (self jump) getRandom(key int32) int32 {
var rbuff int32
for i := 0; i < 30; i++ {
r := self.getZeroOrOne()
rbuff = rbuff << 1
if r == 1 {
rbuff = rbuff | 1
}
}
return rbuff % key
}
func (self *jump) getZeroOrOne() int64 {
rtv := rand.Int63() % 2
return rtv
}
func main() {
rand := jump{max: 10}
for i := 0; i < 10; i++ {
fmt.Println(rand.getRandom(10))
}
}
Random 일반
컴퓨터는 입력에 따라 출력이 정해진다. 따라서 컴퓨터는 의사난수만을 만들 수 있다. 이 입력 값을 Seed라고 한다. Seed 값에 따라서 난수표가 달라진다. Seed를 이용하는 난수 발생기는 Seed를 예측 할 수 있기 때문에, 시간을 이용해서 Seed를 예측하기 힘들게 한다. 보통은 밀리초 단위로 설정하기 때문에 인간 레벨에서 같은 seed를 찾는 건 불가능에 가깝다.
시간을 이용해서 Seed를 예측하기 힘들게 할 수는 있지만, 만들어진 대략적인 시간을 안다면 컴퓨터를 이용해서 계산을 할 수 있기 때문에 안전한 방법은 아니다. 리눅스는 /dev/random과 /dev/urandom 디바이스로 해결하고 있다. 이 디바이스는 Hardware random generator로 IO 디바이스 드라이버에서 발생하는 입력 신호의 노이즈를 모은 정보를 이용해서 난수를 만든다. 이건 컴퓨터를 이용한다고 하더라도 현실적으로 예측 할 수 없기 때문에 매우 안전하게 사용 할 수 있다.
/dev/random과 /dev/urandom의 차이는 노이즈 수집방식에 있다. /dev/random은 노이즈가 충분히 수집되기 전에는 난수를 발생하지 않는다. 즉 블럭킹된다. 실제 난수 입력을 요청하는 몇몇 애플리케이션들은 빠르게 난수를 만들기 위해서 마우스나 키보드 입력을 요구하기도 한다. /dev/urandom은 노이즈가 충분히 수집되지 않아도 블럭킹하지 않고 난수를 만들 수 있다.
아래 예제 코드는 math/rand와 /dev/urandom 예제다.
Jump 기반
Rand Mod 기반
Random 일반
참고
Recent Posts
Archive Posts
Tags