mirror of
				https://github.com/gin-gonic/gin.git
				synced 2025-11-04 01:02:14 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			106 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2020 Gin Core Team. All rights reserved.
 | 
						|
// Use of this source code is governed by a MIT style
 | 
						|
// license that can be found in the LICENSE file.
 | 
						|
 | 
						|
package bytesconv
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	cRand "crypto/rand"
 | 
						|
	"math/rand"
 | 
						|
	"strings"
 | 
						|
	"testing"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	testString = "Albert Einstein: Logic will get you from A to B. Imagination will take you everywhere."
 | 
						|
	testBytes  = []byte(testString)
 | 
						|
)
 | 
						|
 | 
						|
func rawBytesToStr(b []byte) string {
 | 
						|
	return string(b)
 | 
						|
}
 | 
						|
 | 
						|
func rawStrToBytes(s string) []byte {
 | 
						|
	return []byte(s)
 | 
						|
}
 | 
						|
 | 
						|
// go test -v
 | 
						|
 | 
						|
func TestBytesToString(t *testing.T) {
 | 
						|
	data := make([]byte, 1024)
 | 
						|
	for i := 0; i < 100; i++ {
 | 
						|
		_, err := cRand.Read(data)
 | 
						|
		if err != nil {
 | 
						|
			t.Fatal(err)
 | 
						|
		}
 | 
						|
		if rawBytesToStr(data) != BytesToString(data) {
 | 
						|
			t.Fatal("don't match")
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
 | 
						|
const (
 | 
						|
	letterIdxBits = 6                    // 6 bits to represent a letter index
 | 
						|
	letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
 | 
						|
	letterIdxMax  = 63 / letterIdxBits   // # of letter indices fitting in 63 bits
 | 
						|
)
 | 
						|
 | 
						|
var src = rand.New(rand.NewSource(time.Now().UnixNano()))
 | 
						|
 | 
						|
func RandStringBytesMaskImprSrcSB(n int) string {
 | 
						|
	sb := strings.Builder{}
 | 
						|
	sb.Grow(n)
 | 
						|
	// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
 | 
						|
	for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
 | 
						|
		if remain == 0 {
 | 
						|
			cache, remain = src.Int63(), letterIdxMax
 | 
						|
		}
 | 
						|
		if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
 | 
						|
			sb.WriteByte(letterBytes[idx])
 | 
						|
			i--
 | 
						|
		}
 | 
						|
		cache >>= letterIdxBits
 | 
						|
		remain--
 | 
						|
	}
 | 
						|
 | 
						|
	return sb.String()
 | 
						|
}
 | 
						|
 | 
						|
func TestStringToBytes(t *testing.T) {
 | 
						|
	for i := 0; i < 100; i++ {
 | 
						|
		s := RandStringBytesMaskImprSrcSB(64)
 | 
						|
		if !bytes.Equal(rawStrToBytes(s), StringToBytes(s)) {
 | 
						|
			t.Fatal("don't match")
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// go test -v -run=none -bench=^BenchmarkBytesConv -benchmem=true
 | 
						|
 | 
						|
func BenchmarkBytesConvBytesToStrRaw(b *testing.B) {
 | 
						|
	for b.Loop() {
 | 
						|
		rawBytesToStr(testBytes)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func BenchmarkBytesConvBytesToStr(b *testing.B) {
 | 
						|
	for b.Loop() {
 | 
						|
		BytesToString(testBytes)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func BenchmarkBytesConvStrToBytesRaw(b *testing.B) {
 | 
						|
	for b.Loop() {
 | 
						|
		rawStrToBytes(testString)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func BenchmarkBytesConvStrToBytes(b *testing.B) {
 | 
						|
	for b.Loop() {
 | 
						|
		StringToBytes(testString)
 | 
						|
	}
 | 
						|
}
 |