github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/cmn/cos/rand.go (about) 1 // Package cos provides common low-level types and utilities for all aistore projects 2 /* 3 * Copyright (c) 2018-2023, NVIDIA CORPORATION. All rights reserved. 4 */ 5 package cos 6 7 import ( 8 cryptorand "crypto/rand" 9 "encoding/binary" 10 "math/rand" 11 12 "github.com/NVIDIA/aistore/cmn/debug" 13 "github.com/NVIDIA/aistore/cmn/mono" 14 ) 15 16 const ( 17 LetterRunes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 18 LenRunes = len(LetterRunes) 19 20 letterIdxBits = 6 // 6 bits to represent a letter index 21 letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits 22 letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits 23 ) 24 25 /////////// 26 // crand // 27 /////////// 28 29 type crand struct{} 30 31 var crnd rand.Source = &crand{} 32 33 func (*crand) Int63() int64 { 34 var buf [8]byte 35 // crypto/rand uses syscalls or reads from /dev/random (or /dev/urandom) to get random bytes. 36 // See https://golang.org/pkg/crypto/rand/#pkg-variables for more. 37 _, err := cryptorand.Read(buf[:]) 38 debug.AssertNoErr(err) 39 return int64(binary.LittleEndian.Uint64(buf[:])) 40 } 41 42 func (*crand) Seed(int64) {} 43 44 func CryptoRandS(n int) string { return RandStringWithSrc(crnd, n) } 45 46 // 47 // misc. rand utils 48 // 49 50 func RandStringWithSrc(src rand.Source, n int) string { 51 b := make([]byte, n) 52 // src.Int63() generates 63 random bits, enough for letterIdxMax characters 53 for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; { 54 if remain == 0 { 55 cache, remain = src.Int63(), letterIdxMax 56 } 57 if idx := int(cache & letterIdxMask); idx < LenRunes { 58 b[i] = LetterRunes[idx] 59 i-- 60 } 61 cache >>= letterIdxBits 62 remain-- 63 } 64 return string(b) 65 } 66 67 func NowRand() *rand.Rand { 68 return rand.New(rand.NewSource(mono.NanoTime())) 69 }