github.com/newrelic/go-agent@v3.26.0+incompatible/internal/rand.go (about) 1 // Copyright 2020 New Relic Corporation. All rights reserved. 2 // SPDX-License-Identifier: Apache-2.0 3 4 package internal 5 6 import ( 7 "math/rand" 8 "sync" 9 "time" 10 ) 11 12 var ( 13 seededRand = struct { 14 sync.Mutex 15 *rand.Rand 16 }{ 17 Rand: rand.New(rand.NewSource(int64(time.Now().UnixNano()))), 18 } 19 ) 20 21 // RandUint64 returns a random uint64. 22 // 23 // IMPORTANT! The default rand package functions are not used, since we want to 24 // minimize the chance that different Go processes duplicate the same 25 // transaction id. (Note that the rand top level functions "use a default 26 // shared Source that produces a deterministic sequence of values each time a 27 // program is run" (and we don't seed the shared Source to avoid changing 28 // customer apps' behavior)). 29 func RandUint64() uint64 { 30 seededRand.Lock() 31 defer seededRand.Unlock() 32 33 u1 := seededRand.Uint32() 34 u2 := seededRand.Uint32() 35 return (uint64(u1) << 32) | uint64(u2) 36 } 37 38 // RandUint32 returns a random uint32. 39 func RandUint32() uint32 { 40 seededRand.Lock() 41 defer seededRand.Unlock() 42 43 return seededRand.Uint32() 44 } 45 46 // RandFloat32 returns a random float32 between 0.0 and 1.0. 47 func RandFloat32() float32 { 48 seededRand.Lock() 49 defer seededRand.Unlock() 50 51 for { 52 if r := seededRand.Float32(); 0.0 != r { 53 return r 54 } 55 } 56 } 57 58 // RandUint64N returns a random int64 that's 59 // between 0 and the passed in max, non-inclusive 60 func RandUint64N(max uint64) uint64 { 61 return RandUint64() % max 62 }