Ich möchte einen zufälligen String von Zeichen nur (groß- oder kleinschreibung), keine Zahlen, in Go. Was ist der schnellste und einfachste Weg, dies zu tun?
Antworten
Zu viele Anzeigen?
0xcaff
Punkte
11966
Wenn Sie bereit sind, ein paar Zeichen zu Ihrem Pool der erlaubten Zeichen hinzuzufügen, können Sie den Code dazu bringen, mit allem zu funktionieren, was zufällige Bytes über einen io.Reader bereitstellt. Hier verwenden wir crypto/rand
.
// len(encodeURL) == 64. Dies ermöglicht (x <= 265), dass x % 64 eine gleichmäßige
// Verteilung hat.
const encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
// Eine Hilfsfunktion zum Erstellen und Ausfüllen eines Slices der Länge n mit Zeichen aus
// a-zA-Z0-9_-. Sie löst einen Fehler aus, wenn es Probleme beim Abrufen zufälliger Bytes gibt.
func RandAsciiBytes(n int) []byte {
output := make([]byte, n)
// Wir werden n Bytes nehmen, ein Byte für jedes Zeichen der Ausgabe.
randomness := make([]byte, n)
// alle zufälligen Byte lesen
_, err := rand.Read(randomness)
if err != nil {
panic(err)
}
// Ausgabe füllen
for pos := range output {
// zufälliges Element erhalten
random := uint8(randomness[pos])
// zufälliges % 64
randomPos := random % uint8(len(encodeURL))
// in die Ausgabe einfügen
output[pos] = encodeURL[randomPos]
}
return output
}
korzhao
Punkte
9
/*
korzhao
*/
package rand
import (
crand "crypto/rand"
"math/rand"
"sync"
"time"
"unsafe"
)
// Teilt die Zufallsbibliothek nicht global, um Sperrwettbewerb zu reduzieren
type Rand struct {
Seed int64
Pool *sync.Pool
}
var (
MRand = NewRand()
randlist = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
)
// Initialisierung des Zufallszahlengenerators
func NewRand() *Rand {
p := &sync.Pool{New: func() interface{} {
return rand.New(rand.NewSource(getSeed()))
},
}
mrand := &Rand{
Pool: p,
}
return mrand
}
// Holt den Seed
func getSeed() int64 {
return time.Now().UnixNano()
}
func (s *Rand) getrand() *rand.Rand {
return s.Pool.Get().(*rand.Rand)
}
func (s *Rand) putrand(r *rand.Rand) {
s.Pool.Put(r)
}
// Erhalte eine Zufallszahl
func (s *Rand) Intn(n int) int {
r := s.getrand()
defer s.putrand(r)
return r.Intn(n)
}
// Massenhaft erhaltene Zufallszahlen
func (s *Rand) Read(p []byte) (int, error) {
r := s.getrand()
defer s.putrand(r)
return r.Read(p)
}
func CreateRandomString(len int) string {
b := make([]byte, len)
_, err := MRand.Read(b)
if err != nil {
return ""
}
for i := 0; i < len; i++ {
b[i] = randlist[b[i]%(62)]
}
return *(*string)(unsafe.Pointer(&b))
}
24.0 ns/op 16 B/op 1 allocs/
Komu
Punkte
12504
package main
import (
"encoding/base64"
"fmt"
"math/rand"
"time"
)
// customEncodeURL ist wie `bas64.encodeURL`
// außer dass es ausschließlich aus Großbuchstaben besteht:
const customEncodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL"
// Random generiert einen zufälligen String.
// Es ist nicht kryptographisch sicher.
func Random(n int) string {
b := make([]byte, n)
rand.Seed(time.Now().UnixNano())
_, _ = rand.Read(b) // docs say that it always returns a nil error.
customEncoding := base64.NewEncoding(customEncodeURL).WithPadding(base64.NoPadding)
return customEncoding.EncodeToString(b)
}
func main() {
fmt.Println(Random(16))
}
user10987909
Punkte
1
const (
chars = "0123456789_abcdefghijkl-mnopqrstuvwxyz" //ABCDEFGHIJKLMNOPQRSTUVWXYZ
charsLen = len(chars)
mask = 1<<6 - 1
)
var rng = rand.NewSource(time.Now().UnixNano())
// RandStr
func RandStr(ln int) string {
/* chars 38
* rng.Int63() 64bit,6bit(2^6=64) 10
*/
buf := make([]byte, ln)
for idx, cache, remain := ln-1, rng.Int63(), 10; idx >= 0; {
if remain == 0 {
cache, remain = rng.Int63(), 10
}
buf[idx] = chars[int(cache&mask)%charsLen]
cache >>= 6
remain--
idx--
}
return *(*string)(unsafe.Pointer(&buf))
}
BenchmarkRandStr16-8 20000000 68.1 ns/op 16 B/op 1 allocs/op
- See previous answers
- Weitere Antworten anzeigen