github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/go.mongodb.org/mongo-driver/internal/randutil/randutil.go (about)

     1  // Copyright (C) MongoDB, Inc. 2022-present.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"); you may
     4  // not use this file except in compliance with the License. You may obtain
     5  // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
     6  
     7  // Package randutil provides common random number utilities.
     8  package randutil
     9  
    10  import (
    11  	crand "crypto/rand"
    12  	"fmt"
    13  	"io"
    14  
    15  	xrand "go.mongodb.org/mongo-driver/internal/randutil/rand"
    16  )
    17  
    18  // NewLockedRand returns a new "x/exp/rand" pseudo-random number generator seeded with a
    19  // cryptographically-secure random number.
    20  // It is safe to use from multiple goroutines.
    21  func NewLockedRand() *xrand.Rand {
    22  	var randSrc = new(xrand.LockedSource)
    23  	randSrc.Seed(cryptoSeed())
    24  	return xrand.New(randSrc)
    25  }
    26  
    27  // cryptoSeed returns a random uint64 read from the "crypto/rand" random number generator. It is
    28  // intended to be used to seed pseudorandom number generators at package initialization. It panics
    29  // if it encounters any errors.
    30  func cryptoSeed() uint64 {
    31  	var b [8]byte
    32  	_, err := io.ReadFull(crand.Reader, b[:])
    33  	if err != nil {
    34  		panic(fmt.Errorf("failed to read 8 bytes from a \"crypto/rand\".Reader: %v", err))
    35  	}
    36  
    37  	return (uint64(b[0]) << 0) | (uint64(b[1]) << 8) | (uint64(b[2]) << 16) | (uint64(b[3]) << 24) |
    38  		(uint64(b[4]) << 32) | (uint64(b[5]) << 40) | (uint64(b[6]) << 48) | (uint64(b[7]) << 56)
    39  }