投稿

1月, 2017の投稿を表示しています

[golang] crypto/rand で疑似乱数生成器を初期化する

Go 言語で疑似乱数 math/rand を使うとき、実行ごとに別の乱数列を選択するための方法として、rand.Seed(time.Now().UnixNano()) とするのが人気があるようなのですが、より予測困難さを追加するためには以下のコードのようにすると良いです。 今日では、Perl, Ruby, Python などで、明示的な seed をせずに rand を使った場合に、内部的に行われる自動的な seed では、OS の乱数生成器由来の値が使われるようになっているので、Go でも同じ感じで良いと思います。 package main import ( cryptorand "crypto/rand" "encoding/binary" "math/rand" ) func main() { randSeed() println("rand int:", rand.Int()) } func randSeed() { var seed int64 err := binary.Read(cryptorand.Reader, binary.LittleEndian, &seed) if err != nil { panic(err) } rand.Seed(seed) } LittleEndian は BigEndian でも良いです。crypto/rand には big.Int のインターフェースもありますが、こちらの方式の方が簡潔に書けると思います。 蛇足ですが、暗号化用の鍵や、何とかトークンのような、長さ分のエントロピーを持つ乱雑な文字列を作りたい場合は、math/rand ではなく、 crypto/rand をそのまま使う必要があります。 リンク math/rand: Deterministic random by default is dangerous #11871