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?

11voto

Ninh Pham Punkte 5700

Andere Version, inspiriert von Generieren Sie ein Passwort in JavaScript-Crypto:

package main

import (
    "crypto/rand"
    "fmt"
)

var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-"

func shortID(length int) string {
    ll := len(chars)
    b := make([]byte, length)
    rand.Read(b) // Generiert len(b) zufällige Bytes
    for i := 0; i < length; i++ {
        b[i] = chars[int(b[i])%ll]
    }
    return string(b)
}

func main() {
    fmt.Println(shortID(18))
    fmt.Println(shortID(18))
    fmt.Println(shortID(18))
}

6voto

Chris Punkte 601

Nach icza's wunderbar erklärter Lösung, hier eine Modifikation, die anstelle von math/rand crypto/rand verwendet.

const (
    letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" // 52 Möglichkeiten
    letterIdxBits = 6                    // 6 Bits, um 64 Möglichkeiten/Indizes darzustellen
    letterIdxMask = 1<


Wenn Sie eine allgemeinere Lösung möchten, die es Ihnen ermöglicht, das Array der Zeichenbytes zu übergeben, aus dem der String erstellt werden soll, können Sie dies versuchen:

    // SecureRandomString gibt einen String der angeforderten Länge zurück,
    // erstellt aus den bereitgestellten Byte-Zeichen (nur ASCII erlaubt).
    // Verwendet crypto/rand für Sicherheit. Wird einen Fehler auslösen, wenn len(availableCharBytes) > 256.
    func SecureRandomString(availableCharBytes string, length int) string {

        // Bit-Maske berechnen
        availableCharLength := len(availableCharBytes)
        if availableCharLength == 0 || availableCharLength > 256 {
            panic("Die Länge von availableCharBytes muss größer als 0 und kleiner oder gleich 256 sein")
        }
        var bitLength byte
        var bitMask byte
        for bits := availableCharLength - 1; bits != 0; {
            bits = bits >> 1
            bitLength++
        }
        bitMask = 1<

``

Wenn Sie Ihre eigene Zufallsquelle übergeben möchten, wäre es einfach, das obige zu modifizieren, um anstelle von `crypto/rand` einen `io.Reader` zu akzeptieren.

`` ```

5voto

Dima Punkte 177

Hier ist mein Weg) Verwenden Sie Mathematikrand oder Cryptorand, wie Sie möchten.

func randStr(len int) string {
    buff := make([]byte, len)
    rand.Read(buff)
    str := base64.StdEncoding.EncodeToString(buff)
    // Base 64 kann länger als len sein
    return str[:len]
}

4voto

th3morg Punkte 3901

Ich verwende die UUID-Bibliothek von Google in vielen meiner Projekte, was es mir ermöglicht, dies leicht zu tun:

uuid.NewString()[:Länge]

Es erfüllt zumindest das Kriterium für Einfachheit.

https://go.dev/play/p/5sWDsGqglAi

3voto

twharmon Punkte 4215

Hier ist eine einfache und leistungsstarke Lösung.

package main

import (
    "crypto/rand"
    "unsafe"
    "fmt"
)

var alphabet = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

func main() {
    fmt.Println(generate(16))
}

func generate(size int) string {
    b := make([]byte, size)
    rand.Read(b)
    for i := 0; i < size; i++ {
        b[i] = alphabet[b[i] % byte(len(alphabet))]
    }
    return *(*string)(unsafe.Pointer(&b))
}

Benchmark

Benchmark  95.2 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