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?

218voto

Paul Hankin Punkte 49669

Sie können einfach Code dafür schreiben. Dieser Code kann etwas einfacher sein, wenn Sie sich darauf verlassen möchten, dass alle Buchstaben beim Codieren in UTF-8 einzelne Bytes sind.

package main

import (
    "fmt"
    "time"
    "math/rand"
)

func init() {
    rand.Seed(time.Now().UnixNano())
}

var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

func randSeq(n int) string {
    b := make([]rune, n)
    for i := range b {
        b[i] = letters[rand.Intn(len(letters))]
    }
    return string(b)
}

func main() {
    fmt.Println(randSeq(10))
}

35voto

dchest Punkte 1502

Verwenden Sie das Paket uniuri, das kryptographisch sichere gleichmäßige (unvoreingenommene) Zeichenfolgen generiert.

Haftungsausschluss: Ich bin der Autor des Pakets

30voto

Amin Shojaei Punkte 3558

Einfache Lösung für Sie, mit dem geringsten Duplikatergebnis:

import (
    "fmt"
    "math/rand"
    "time"
)

func randomString(length int) string {
    rand.Seed(time.Now().UnixNano())
    b := make([]byte, length+2)
    rand.Read(b)
    return fmt.Sprintf("%x", b)[2 : length+2]
}

Schau es dir im PlayGround an

20voto

Not_a_Golfer Punkte 45532

Zwei mögliche Optionen (es könnte natürlich mehr geben):

  1. Sie können das crypto/rand Paket verwenden, das das Lesen von zufälligen Byte-Arrays (aus /dev/urandom) unterstützt und auf die kryptografische Zufallsgenerierung ausgerichtet ist. siehe http://golang.org/pkg/crypto/rand/#example_Read . Es könnte jedoch langsamer sein als die normale pseudozufällige Nummerngenerierung.

  2. Nehmen Sie eine Zufallszahl und hashen Sie sie mit md5 oder etwas Ähnlichem.

12voto

Steven Soroka Punkte 18749

Wenn Sie kryptographisch sichere Zufallszahlen möchten und das genaue Zeichensatz flexibel ist (zum Beispiel ist base64 in Ordnung), können Sie genau berechnen, wie viele zufällige Zeichen Sie aus der gewünschten Ausgabegröße benötigen.

Base-64-Text ist 1/3 länger als Base-256. (2^8 vs 2^6; 8Bits/6Bits = 1,333 Verhältnis)

import (
    "crypto/rand"
    "encoding/base64"
    "math"
)

func randomBase64String(l int) string {
    buff := make([]byte, int(math.Ceil(float64(l)/float64(1.33333333333))))
    rand.Read(buff)
    str := base64.RawURLEncoding.EncodeToString(buff)
    return str[:l] // 1 zusätzliches Zeichen entfernen, das wir bei ungeraden Längen erhalten
}

Hinweis: Sie können auch RawStdEncoding verwenden, wenn Sie + und / Zeichen - und _ vorziehen.

Wenn Sie Hex verwenden möchten, ist Base-16 doppelt so lang wie Base-256. (2^8 vs 2^4; 8Bits/4Bits = 2x Verhältnis)

import (
    "crypto/rand"
    "encoding/hex"
    "math"
)

func randomBase16String(l int) string {
    buff := make([]byte, int(math.Ceil(float64(l)/2)))
    rand.Read(buff)
    str := hex.EncodeToString(buff)
    return str[:l] // 1 zusätzliches Zeichen entfernen, das wir bei ungeraden Längen erhalten
}

Sie könnten dies jedoch auf einen beliebigen Zeichensatz erweitern, wenn Sie einen Base256- zu BaseN-Encoder für Ihren Zeichensatz haben. Sie können dieselbe Größenberechnung mit der Anzahl der für Ihren Zeichensatz benötigten Bits durchführen. Die Verhältnisberechnung für einen beliebigen Zeichensatz lautet: Verhältnis = 8 / log2(len(zeichensatz))).

Obwohl beide Lösungen sicher, einfach, schnell sein sollten und Ihren Krypto-Entropie-Pool nicht verschwenden sollten.

Hier finden Sie den Playground, der zeigt, dass es für jede Größe funktioniert. https://play.golang.org/p/_yF_xxXer0Z

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