486 Stimmen

Wie generiert man einen Zufalls-String einer festen Länge in Go?

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?

0voto

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
}

-1voto

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/

-3voto

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))
}

-3voto

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X