56 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			56 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
	
package ksuid
 | 
						|
 | 
						|
import (
 | 
						|
	cryptoRand "crypto/rand"
 | 
						|
	"encoding/binary"
 | 
						|
	"io"
 | 
						|
	"math/rand"
 | 
						|
)
 | 
						|
 | 
						|
// FastRander is an io.Reader that uses math/rand and is optimized for
 | 
						|
// generating 16 bytes KSUID payloads. It is intended to be used as a
 | 
						|
// performance improvements for programs that have no need for
 | 
						|
// cryptographically secure KSUIDs and are generating a lot of them.
 | 
						|
var FastRander = newRBG()
 | 
						|
 | 
						|
func newRBG() io.Reader {
 | 
						|
	r, err := newRandomBitsGenerator()
 | 
						|
	if err != nil {
 | 
						|
		panic(err)
 | 
						|
	}
 | 
						|
	return r
 | 
						|
}
 | 
						|
 | 
						|
func newRandomBitsGenerator() (r io.Reader, err error) {
 | 
						|
	var seed int64
 | 
						|
 | 
						|
	if seed, err = readCryptoRandomSeed(); err != nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	r = &randSourceReader{source: rand.NewSource(seed).(rand.Source64)}
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
func readCryptoRandomSeed() (seed int64, err error) {
 | 
						|
	var b [8]byte
 | 
						|
 | 
						|
	if _, err = io.ReadFull(cryptoRand.Reader, b[:]); err != nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	seed = int64(binary.LittleEndian.Uint64(b[:]))
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
type randSourceReader struct {
 | 
						|
	source rand.Source64
 | 
						|
}
 | 
						|
 | 
						|
func (r *randSourceReader) Read(b []byte) (int, error) {
 | 
						|
	// optimized for generating 16 bytes payloads
 | 
						|
	binary.LittleEndian.PutUint64(b[:8], r.source.Uint64())
 | 
						|
	binary.LittleEndian.PutUint64(b[8:], r.source.Uint64())
 | 
						|
	return 16, nil
 | 
						|
}
 |