From 8161583fa12ab8deeb6ab6caf7629ac7c439e3ad Mon Sep 17 00:00:00 2001 From: liyichao Date: Thu, 30 Sep 2021 19:38:37 +0800 Subject: [PATCH] feat: add fastrand.Read() --- lang/fastrand/fastrand.go | 27 +++++++++++++++++++++++++++ lang/fastrand/fastrand_test.go | 3 +++ 2 files changed, 30 insertions(+) diff --git a/lang/fastrand/fastrand.go b/lang/fastrand/fastrand.go index 34952e20..153b2371 100644 --- a/lang/fastrand/fastrand.go +++ b/lang/fastrand/fastrand.go @@ -16,6 +16,8 @@ package fastrand import ( + "unsafe" + "github.com/bytedance/gopkg/internal/runtimex" ) @@ -121,3 +123,28 @@ func Uint32n(n uint32) uint32 { func Uint64n(n uint64) uint64 { return Uint64() % n } + +// Read generates len(p) random bytes and writes them into p. +// It always returns len(p) and a nil error. And it is safe +// for concurrent use. +func Read(p []byte) (n int, err error) { + l := len(p) + + if l >= 4 { + i := 0 + uint32p := *(*[]uint32)(unsafe.Pointer(&p)) + for ; l >= 4; l -= 4 { + uint32p[i] = Uint32() + i++ + } + } + + if l > 0 { + r := Uint32() + for ; l > 0; l-- { + p[len(p)-l] = byte(r >> (l * 8)) + } + } + + return len(p), nil +} diff --git a/lang/fastrand/fastrand_test.go b/lang/fastrand/fastrand_test.go index 2ca1a971..a8dd121c 100644 --- a/lang/fastrand/fastrand_test.go +++ b/lang/fastrand/fastrand_test.go @@ -21,6 +21,9 @@ import ( func TestAll(t *testing.T) { _ = Uint32() + + bytes := make([]byte, 1000) + _, _ = Read(bytes) } func BenchmarkSingleCore(b *testing.B) {