diff --git a/examples/internal/signal/rand.go b/examples/internal/signal/rand.go index e729bd4b..49b5e833 100644 --- a/examples/internal/signal/rand.go +++ b/examples/internal/signal/rand.go @@ -2,16 +2,17 @@ package signal import ( "math/rand" - "time" ) // RandSeq generates a random string to serve as dummy data +// +// It returns a deterministic sequence of values each time a program is run. +// Use rand.Seed() function in your real applications. func RandSeq(n int) string { - r := rand.New(rand.NewSource(time.Now().UnixNano())) letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") b := make([]rune, n) for i := range b { - b[i] = letters[r.Intn(len(letters))] + b[i] = letters[rand.Intn(len(letters))] } return string(b) } diff --git a/go.mod b/go.mod index 16bfb7e4..b37ff9bc 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/pion/ice/v2 v2.0.0-rc.4 github.com/pion/logging v0.2.2 github.com/pion/quic v0.1.1 + github.com/pion/randutil v0.0.0 github.com/pion/rtcp v1.2.3 github.com/pion/rtp v1.5.5 github.com/pion/sctp v1.7.6 diff --git a/go.sum b/go.sum index ca840773..e32d5c4e 100644 --- a/go.sum +++ b/go.sum @@ -39,6 +39,8 @@ github.com/pion/mdns v0.0.4 h1:O4vvVqr4DGX63vzmO6Fw9vpy3lfztVWHGCQfyw0ZLSY= github.com/pion/mdns v0.0.4/go.mod h1:R1sL0p50l42S5lJs91oNdUL58nm0QHrhxnSegr++qC0= github.com/pion/quic v0.1.1 h1:D951FV+TOqI9A0rTF7tHx0Loooqz+nyzjEyj8o3PuMA= github.com/pion/quic v0.1.1/go.mod h1:zEU51v7ru8Mp4AUBJvj6psrSth5eEFNnVQK5K48oV3k= +github.com/pion/randutil v0.0.0 h1:aLWLVhTG2jzoD25F0OlW6nXvXrjoGwiXq2Sz7j7NzL0= +github.com/pion/randutil v0.0.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= github.com/pion/rtcp v1.2.3 h1:2wrhKnqgSz91Q5nzYTO07mQXztYPtxL8a0XOss4rJqA= github.com/pion/rtcp v1.2.3/go.mod h1:zGhIv0RPRF0Z1Wiij22pUt5W/c9fevqSzT4jje/oK7I= github.com/pion/rtp v1.5.5 h1:WTqWdmBuIj+luh8Wg6XVX+w7OytZHAIgtC7uSvgEl9Y= diff --git a/internal/util/util.go b/internal/util/util.go index 3cb02520..a1c49f3e 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -2,20 +2,26 @@ package util import ( - "math/rand" "strings" - "time" + + "github.com/pion/randutil" ) -// RandSeq generates a random alpha numeric sequence of the requested length -func RandSeq(n int) string { - r := rand.New(rand.NewSource(time.Now().UnixNano())) - letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") - b := make([]rune, n) - for i := range b { - b[i] = letters[r.Intn(len(letters))] - } - return string(b) +const ( + runesAlpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +) + +// Use global random generator to properly seed by crypto grade random. +var globalMathRandomGenerator = randutil.NewMathRandomGenerator() // nolint:gochecknoglobals + +// MathRandAlpha generates a mathmatical random alphabet sequence of the requested length. +func MathRandAlpha(n int) string { + return globalMathRandomGenerator.GenerateString(n, runesAlpha) +} + +// RandUint32 generates a mathmatical random uint32. +func RandUint32() uint32 { + return globalMathRandomGenerator.Uint32() } // FlattenErrs flattens multiple errors into one diff --git a/internal/util/util_test.go b/internal/util/util_test.go index b1e479b1..199775bf 100644 --- a/internal/util/util_test.go +++ b/internal/util/util_test.go @@ -6,14 +6,14 @@ import ( "testing" ) -func TestRandSeq(t *testing.T) { - if len(RandSeq(10)) != 10 { - t.Errorf("RandSeq return invalid length") +func TestMathRandAlpha(t *testing.T) { + if len(MathRandAlpha(10)) != 10 { + t.Errorf("MathRandAlpha return invalid length") } var isLetter = regexp.MustCompile(`^[a-zA-Z]+$`).MatchString - if !isLetter(RandSeq(10)) { - t.Errorf("RandSeq should be AlphaNumeric only") + if !isLetter(MathRandAlpha(10)) { + t.Errorf("MathRandAlpha should be AlphaNumeric only") } } diff --git a/peerconnection.go b/peerconnection.go index 68cc1465..fb71fbd7 100644 --- a/peerconnection.go +++ b/peerconnection.go @@ -8,7 +8,6 @@ import ( "crypto/elliptic" "crypto/rand" "fmt" - mathRand "math/rand" "strconv" "strings" "sync" @@ -1272,7 +1271,7 @@ func (pc *PeerConnection) AddTransceiverFromKind(kind RTPCodecType, init ...RtpT return nil, fmt.Errorf("no %s codecs found", kind.String()) } - track, err := pc.NewTrack(codecs[0].PayloadType, mathRand.Uint32(), util.RandSeq(trackDefaultIDLength), util.RandSeq(trackDefaultLabelLength)) + track, err := pc.NewTrack(codecs[0].PayloadType, util.RandUint32(), util.MathRandAlpha(trackDefaultIDLength), util.MathRandAlpha(trackDefaultLabelLength)) if err != nil { return nil, err } diff --git a/peerconnection_go_test.go b/peerconnection_go_test.go index ea2bd94e..465f8018 100644 --- a/peerconnection_go_test.go +++ b/peerconnection_go_test.go @@ -143,9 +143,9 @@ func TestNew_Go(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, pc) - pc.configuration.ICEServers[0].Username = util.RandSeq(15) - pc.configuration.ICEServers[0].Credential = util.RandSeq(15) - pc.configuration.ICEServers[0].URLs[0] = util.RandSeq(15) + pc.configuration.ICEServers[0].Username = util.MathRandAlpha(15) // Tests doesn't need crypto random + pc.configuration.ICEServers[0].Credential = util.MathRandAlpha(15) + pc.configuration.ICEServers[0].URLs[0] = util.MathRandAlpha(15) assert.Equal(t, expectedUsername, cfg.ICEServers[0].Username) assert.Equal(t, expectedPassword, cfg.ICEServers[0].Credential) diff --git a/peerconnection_renegotiation_test.go b/peerconnection_renegotiation_test.go index 975b7153..640216e0 100644 --- a/peerconnection_renegotiation_test.go +++ b/peerconnection_renegotiation_test.go @@ -147,7 +147,7 @@ func TestPeerConnection_Renegotiation_AddTrack_Multiple(t *testing.T) { return track } - trackNames := []string{util.RandSeq(trackDefaultIDLength), util.RandSeq(trackDefaultIDLength), util.RandSeq(trackDefaultIDLength)} + trackNames := []string{util.MathRandAlpha(trackDefaultIDLength), util.MathRandAlpha(trackDefaultIDLength), util.MathRandAlpha(trackDefaultIDLength)} outboundTracks := []*Track{} onTrackCount := map[string]int{} onTrackChan := make(chan struct{}, 1)