From d257e554dd6e41cbc6887ceab45f224cd2c619f2 Mon Sep 17 00:00:00 2001 From: john Date: Mon, 5 Nov 2018 13:53:17 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9Bgrand=E9=9A=8F=E6=9C=BA?= =?UTF-8?q?=E6=95=B0=E7=94=9F=E6=88=90=E8=AE=BE=E8=AE=A1=EF=BC=8C=E5=BA=95?= =?UTF-8?q?=E5=B1=82=E4=BD=BF=E7=94=A8crypto/rand+=E7=BC=93=E5=86=B2?= =?UTF-8?q?=E5=8C=BA=E5=AE=9E=E7=8E=B0=E9=AB=98=E9=80=9F=E7=9A=84=E9=9A=8F?= =?UTF-8?q?=E6=9C=BA=E6=95=B0=E7=94=9F=E6=88=90=EF=BC=9Bgtime=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E5=A2=9E=E5=8A=A0FuncCost=E5=87=BD=E6=95=B0=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E8=80=97=E6=97=B6=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/net/ghttp/ghttp_server_session.go | 2 +- g/os/gtime/gtime.go | 7 +++ g/util/gconv/gconv.go | 2 +- g/util/grand/grand.go | 9 ---- g/util/grand/grand_intn.go | 45 ++++++++++++++++ g/util/grand/grand_test.go | 2 +- geg/other/test.go | 10 ++-- geg/util/grand/grand.go | 12 +++++ geg/util/grand/rand.go | 83 +++++++++++++++++++++++++++++ 9 files changed, 154 insertions(+), 18 deletions(-) create mode 100644 g/util/grand/grand_intn.go create mode 100644 geg/util/grand/grand.go create mode 100644 geg/util/grand/rand.go diff --git a/g/net/ghttp/ghttp_server_session.go b/g/net/ghttp/ghttp_server_session.go index fd84204cf..c74687d2b 100644 --- a/g/net/ghttp/ghttp_server_session.go +++ b/g/net/ghttp/ghttp_server_session.go @@ -26,7 +26,7 @@ type Session struct { server *Server // 所属Server } -// 生成一个唯一的sessionid字符串 +// 生成一个唯一的sessionid字符串,长度16 func makeSessionId() string { return strings.ToUpper(strconv.FormatInt(gtime.Nanosecond(), 32) + grand.RandStr(3)) } diff --git a/g/os/gtime/gtime.go b/g/os/gtime/gtime.go index ee4d121d5..45f8d95d7 100644 --- a/g/os/gtime/gtime.go +++ b/g/os/gtime/gtime.go @@ -306,4 +306,11 @@ func ParseTimeFromContent(content string, format...string) *Time { } } return nil +} + +// 计算函数f执行的时间,单位纳秒 +func FuncCost(f func()) int64 { + t := Nanosecond() + f() + return Nanosecond() - t } \ No newline at end of file diff --git a/g/util/gconv/gconv.go b/g/util/gconv/gconv.go index dfc435b65..36b0bf678 100644 --- a/g/util/gconv/gconv.go +++ b/g/util/gconv/gconv.go @@ -15,7 +15,7 @@ import ( "strings" ) -// 将变量i转换为字符串指定的类型t,非必须参数extraParams泳衣额外的参数传递 +// 将变量i转换为字符串指定的类型t,非必须参数extraParams用以额外的参数传递 func Convert(i interface{}, t string, extraParams...interface{}) interface{} { switch t { case "int": return Int(i) diff --git a/g/util/grand/grand.go b/g/util/grand/grand.go index 549889d0a..a9d581fdf 100644 --- a/g/util/grand/grand.go +++ b/g/util/grand/grand.go @@ -7,18 +7,9 @@ // 随机数管理 package grand -import ( - "time" -) - var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") var digits = []rune("0123456789") -// 自定义的 rand.Intn -func intn (max int) int { - return int(time.Now().UnixNano())%max -} - // 获得一个 min, max 之间的随机数(min <= x <= max) func Rand (min, max int) int { if min >= max { diff --git a/g/util/grand/grand_intn.go b/g/util/grand/grand_intn.go new file mode 100644 index 000000000..effd207bd --- /dev/null +++ b/g/util/grand/grand_intn.go @@ -0,0 +1,45 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package grand + +import ( + "crypto/rand" + "encoding/binary" +) + +const ( + gBUFFER_SIZE = 10000 // 缓冲区uint64数量大小 +) + +var ( + bufferChan = make(chan uint64, gBUFFER_SIZE) +) + +// 使用缓冲区实现快速的随机数生成 +func init() { + buffer := make([]byte, 1024) + go func() { + for { + if n, err := rand.Read(buffer); err != nil { + panic(err) + } else { + for i := 0; i < n - 8; i += 8 { + bufferChan <- binary.LittleEndian.Uint64(buffer[i : i + 8]) + } + } + } + }() +} + +// 自定义的 rand.Intn ,绝对随机 +func intn (max int) int { + n := int(<- bufferChan)%max + if n < 0 { + return -n + } + return n +} diff --git a/g/util/grand/grand_test.go b/g/util/grand/grand_test.go index f3bd601d8..c87323415 100644 --- a/g/util/grand/grand_test.go +++ b/g/util/grand/grand_test.go @@ -15,6 +15,6 @@ import ( func Benchmark_Rand(b *testing.B) { for i := 0; i < b.N; i++ { - grand.Rand(0, 200) + grand.Rand(0, 999999999) } } diff --git a/geg/other/test.go b/geg/other/test.go index 875b100a4..aa0d5b0f5 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -3,13 +3,11 @@ package main import ( "fmt" "gitee.com/johng/gf/g/os/gtime" + "strconv" ) func main() { - s := ` -[INFO] 2018-11-04 12:48:01 2018-11-04 12:48:01 ["handle eventMedlinker\\Med3Svr\\App\\Events\\Task\\InviteUserVerifyEvent::__set_state(array(\n 'deviceNum' => '25a715ff8d4835197299d7dab067841e',\n 'userIdList' => \n array (\n 0 => '62506063',\n ),\n 'dataId' => '',\n 'eventTime' => NULL,\n))"] [med3-svr-6c8c9b9f4f-fl6g9] - -` - t := gtime.ParseTimeFromContent(s) - fmt.Println(t.String()) + fmt.Println(strconv.FormatInt(gtime.Nanosecond(), 32)) + fmt.Println(gtime.Second()) + fmt.Println(gtime.Nanosecond()) } \ No newline at end of file diff --git a/geg/util/grand/grand.go b/geg/util/grand/grand.go new file mode 100644 index 000000000..1adef54c9 --- /dev/null +++ b/geg/util/grand/grand.go @@ -0,0 +1,12 @@ +package main + +import ( + "fmt" + "gitee.com/johng/gf/g/util/grand" +) + +func main() { + for i := 0; i < 10; i++ { + fmt.Println(grand.Rand(0, 99999)) + } +} diff --git a/geg/util/grand/rand.go b/geg/util/grand/rand.go new file mode 100644 index 000000000..94ffb0091 --- /dev/null +++ b/geg/util/grand/rand.go @@ -0,0 +1,83 @@ +package main + +import ( + crand "crypto/rand" + "encoding/binary" + "fmt" + "gitee.com/johng/gf/g/os/gtime" + mrand "math/rand" + "os" + "time" +) + +// int 随机 +func a1() { + s1 := mrand.NewSource(time.Now().UnixNano()) + r1 := mrand.New(s1) + for i := 0; i < 10; i++ { + fmt.Printf("%d ", r1.Intn(100)) + } + fmt.Printf("\n") +} + +// 0/1 true/false 随机 +func a2() { + // Go编程这本书上例子. + ch := make(chan int, 1) + for i := 0; i < 10; i++ { + select { + case ch <- 0: + case ch <- 1: + } + r := <-ch + fmt.Printf("%d ", r) + } + fmt.Printf("\n") +} + +//真随机 -- 用标准库封装好的 +func a3() { + b := make([]byte, 16) + // On Unix-like systems, Reader reads from /dev/urandom. + // On Windows systems, Reader uses the CryptGenRandom API. + _, err := crand.Read(b) //返回长度为0 - 32 的值 + if err != nil { + fmt.Println("[a3] ", err) + return + } + fmt.Println("[a3] b:", b) +} + +//真随机 -- 我们直接调真随机文件生成了事。 但注意,它是阻塞式的。 +func a4() { + f, err := os.Open("/dev/random") + if err != nil { + fmt.Println("[a4] ", err) + return + } + defer f.Close() + + b1 := make([]byte, 16) + _, err = f.Read(b1) + if err != nil { + fmt.Println("[a4] ", err) + return + } + fmt.Println("[a4] Read /dev/random:", b1) +} + +// a3 的另一种实现方式 +func a5() { + var ret int32 + binary.Read(crand.Reader, binary.LittleEndian, &ret) + fmt.Println("[a5] ret:", ret) +} + +func main() { + fmt.Println("a1:", gtime.FuncCost(a1)) + fmt.Println("a2:", gtime.FuncCost(a2)) + fmt.Println("a3:", gtime.FuncCost(a3)) + fmt.Println("a4:", gtime.FuncCost(a4)) + fmt.Println("a5:", gtime.FuncCost(a5)) +} +