Ich möchte eine Zeichenfolge der Größe N generieren.
Es sollte aus Zahlen und englischen Großbuchstaben bestehen, wie z.
- 6U1S75
- 4Z4UKK
- U911K4
Wie kann ich dies auf pythonische Weise erreichen?
Ich möchte eine Zeichenfolge der Größe N generieren.
Es sollte aus Zahlen und englischen Großbuchstaben bestehen, wie z.
Wie kann ich dies auf pythonische Weise erreichen?
Antworten:
Antwort in einer Zeile:
oder noch kürzer ab Python 3.6 mit
random.choices()
:Eine kryptografisch sicherere Version; Siehe https://stackoverflow.com/a/23728630/2213647 :
Im Detail mit einer sauberen Funktion zur weiteren Wiederverwendung:
Wie funktioniert es ?
Wir importieren
string
ein Modul, das Sequenzen gemeinsamer ASCII-Zeichen enthält, undrandom
ein Modul, das sich mit der Zufallsgenerierung befasst.string.ascii_uppercase + string.digits
Verkettet nur die Liste der Zeichen, die ASCII-Zeichen und -Ziffern in Großbuchstaben darstellen:Dann verwenden wir ein Listenverständnis, um eine Liste von 'n' Elementen zu erstellen:
Im obigen Beispiel wird
[
die Liste verwendet, jedoch nicht in derid_generator
Funktion, sodass Python die Liste nicht im Speicher erstellt, sondern die Elemente im laufenden Betrieb einzeln generiert (mehr dazu hier ).Anstatt zu fragen,
elem
ob 'n' mal die Zeichenfolge erstellt werden soll , bitten wir Python, 'n' mal ein zufälliges Zeichen zu erstellen, das aus einer Folge von Zeichen ausgewählt wird:Daher wird
random.choice(chars) for _ in range(size)
wirklich eine Folge vonsize
Zeichen erstellt. Charaktere, die zufällig ausgewählt werden auschars
:Dann verbinden wir sie einfach mit einer leeren Zeichenfolge, sodass die Sequenz zu einer Zeichenfolge wird:
quelle
range
mitxrange
.random
mitrandom.SystemRandom()
: github.com/django/django/blob/...random.sample
erstellt ersatzlose Samples, dh ohne die Möglichkeit, Zeichen zu wiederholen, was nicht den Anforderungen des OP entspricht. Ich denke nicht, dass dies für die meisten Anwendungen wünschenswert wäre.Diese Stack Overflow-Frage ist das aktuelle Top-Google-Ergebnis für "Random String Python". Die aktuelle Top-Antwort lautet:
Dies ist eine ausgezeichnete Methode, aber das zufällige PRNG ist nicht kryptografisch sicher. Ich gehe davon aus, dass viele Leute, die diese Frage untersuchen, zufällige Zeichenfolgen für die Verschlüsselung oder Passwörter generieren möchten. Sie können dies sicher tun, indem Sie den obigen Code geringfügig ändern:
Verwenden
random.SystemRandom()
von / dev / urandom anstelle von nur zufälligen Verwendungen auf * nix-Computern undCryptGenRandom()
in Windows. Dies sind kryptografisch sichere PRNGs. Die Verwendungrandom.choice
anstellerandom.SystemRandom().choice
einer Anwendung, die ein sicheres PRNG erfordert, kann möglicherweise verheerend sein. Angesichts der Beliebtheit dieser Frage wette ich, dass der Fehler bereits viele Male gemacht wurde.Wenn Sie python3.6 oder höher verwenden, können Sie die neuen verwenden Geheimnisse Modul wie in erwähnt MSeifert Antwort :
In den Moduldokumenten werden auch praktische Möglichkeiten zum Generieren sicherer Token und Best Practices erläutert .
quelle
random
hat dies gewarnt: " Warnung : Die Pseudozufallsgeneratoren dieses Moduls sollten nicht aus Sicherheitsgründen verwendet werden. Verwenden Sie os.urandom () oder SystemRandom, wenn Sie einen kryptografisch sicheren Pseudozufallszahlengenerator benötigen. "" Hier ist die Referenz : random.SystemRandom und os.urandomstring.uppercase
was je nach festgelegtem Gebietsschema zu unerwarteten Ergebnissen führen kann. Die Verwendungstring.ascii_uppercase
(oderstring.ascii_letters + string.digits
für base62 anstelle von base36) ist in Fällen, in denen die Codierung erforderlich ist, sicherer.xrange
anstattrange
wie diese erzeugt eine In-Memory - Liste, während erstere einen Iterator erzeugt.Verwenden Sie einfach die in Python integrierte UUID:
Wenn UUIDs für Ihre Zwecke in Ordnung sind, verwenden Sie das integrierte UUID- Paket.
Einzeilige Lösung:
import uuid; uuid.uuid4().hex.upper()[0:6]
In der Tiefenversion:
Beispiel:
Wenn Sie genau Ihr Format benötigen (z. B. "6U1S75"), können Sie dies folgendermaßen tun:
quelle
string_length
ist, kann die Wahrscheinlichkeit einer Kollision ein Problem sein.Eine einfachere, schnellere, aber etwas weniger zufällige Methode ist die Verwendung,
random.sample
anstatt jeden Buchstaben einzeln auszuwählen. Wenn n-Wiederholungen zulässig sind, vergrößern Sie Ihre zufällige Basis um das n-fache, zHinweis: random.sample verhindert die Wiederverwendung von Zeichen. Das Multiplizieren der Größe des Zeichensatzes ermöglicht mehrere Wiederholungen, aber sie sind immer noch weniger wahrscheinlich als eine rein zufällige Auswahl. Wenn wir uns für eine Zeichenfolge mit der Länge 6 entscheiden und 'X' als erstes Zeichen auswählen, sind im Auswahlbeispiel die Chancen, 'X' für das zweite Zeichen zu erhalten, die gleichen wie die Chancen, 'X' als das zu erhalten erstes Zeichen. In der random.sample-Implementierung beträgt die Wahrscheinlichkeit, 'X' als nachfolgendes Zeichen zu erhalten, nur 6/7 der Wahrscheinlichkeit, es als erstes Zeichen zu erhalten
quelle
sample
Ihnen niemals derselbe Charakter zweimal aufgelistet wird. Auch wird es natürlich fürN
höher als scheitern36
.lowercase_str
ist ein zufälliger Wert wie'cea8b32e00934aaea8c005a35d85a5c0'
uppercase_str
ist'CEA8B32E00934AAEA8C005A35D85A5C0'
quelle
uppercase_str[:N+1]
Eine schnellere, einfachere und flexiblere Möglichkeit, dies zu tun, ist die Verwendung des
strgen
Moduls (pip install StringGenerator
).Generieren Sie eine 6-stellige Zufallszeichenfolge mit Großbuchstaben und Ziffern:
Erhalten Sie eine eindeutige Liste:
Garantieren Sie ein "Sonderzeichen" in der Zeichenfolge:
Eine zufällige HTML-Farbe:
usw.
Wir müssen uns bewusst sein, dass dies:
Möglicherweise ist keine Ziffer (oder kein Großbuchstabe) enthalten.
strgen
ist in der Entwicklerzeit schneller als jede der oben genannten Lösungen. Die Lösung von Ignacio bietet die schnellste Laufzeit und ist die richtige Antwort mit der Python-Standardbibliothek. Aber Sie werden es in dieser Form kaum jemals benutzen. Sie möchten SystemRandom (oder Fallback, falls nicht verfügbar) verwenden, sicherstellen, dass die erforderlichen Zeichensätze dargestellt werden, Unicode verwenden (oder nicht), sicherstellen, dass aufeinanderfolgende Aufrufe eine eindeutige Zeichenfolge erzeugen, eine Teilmenge einer der Zeichenklassen des Zeichenfolgenmoduls verwenden. usw. Dies alles erfordert viel mehr Code als in den bereitgestellten Antworten. Die verschiedenen Versuche, eine Lösung zu verallgemeinern, weisen alle Einschränkungen auf, die strgen mit einer einfachen Vorlagensprache mit größerer Kürze und Ausdruckskraft löst.Es ist auf PyPI:
Offenlegung: Ich bin der Autor des strgen-Moduls.
quelle
Ab Python 3.6 sollten Sie das
secrets
Modul verwenden, wenn es anstelle desrandom
Moduls kryptografisch sicher sein soll (ansonsten ist diese Antwort identisch mit der von @Ignacio Vazquez-Abrams):Ein zusätzlicher Hinweis: Ein Listenverständnis ist bei
str.join
Verwendung eines Generatorausdrucks schneller !quelle
Basierend auf einer anderen Stack Overflow-Antwort wäre die leichteste Methode zum Erstellen einer zufälligen Zeichenfolge und einer zufälligen Hexadezimalzahl eine bessere Version als die akzeptierte Antwort:
viel schneller.
quelle
N
.Wenn Sie eine zufällige Zeichenfolge anstelle einer pseudozufälligen benötigen , sollten Sie diese
os.urandom
als Quelle verwendenquelle
os.urandom
nicht pseudozufällig? Es könnte einen besseren Algorithmus verwenden, um Zahlen zu generieren, die zufälliger sind, aber es ist immer noch pseudozufällig./dev/random
und bewusst/dev/urandom
. Das Problem ist, dass/dev/random
blockiert, wenn nicht genügend Entropie vorhanden ist, was die Nützlichkeit einschränkt. Zum einen ist ein einmaliges Pad/dev/urandom
nicht gut genug, aber ich denke, es ist hier besser als Pseudozufällig./dev/random
und/dev/urandom
pseudozufällig sind, aber es könnte von Ihrer Definition abhängen.Ich dachte, noch hätte niemand darauf geantwortet lol! Aber hey, hier ist mein eigener Versuch:
quelle
Diese Methode ist etwas schneller und etwas ärgerlicher als die von Ignacio veröffentlichte random.choice () -Methode.
Es nutzt die Natur von Pseudozufallsalgorithmen und setzt darauf, dass bitweise und Verschiebung schneller sind als das Generieren einer neuen Zufallszahl für jedes Zeichen.
... einen Generator erstellen, der jeweils 5-Bit-Zahlen 0..31 herausnimmt, bis keine mehr übrig sind
... verbinden () die Ergebnisse des Generators mit einer Zufallszahl mit den richtigen Bits
Bei Timeit war das Timing für Zeichenfolgen mit 32 Zeichen:
... aber bei 64 Zeichenketten verlieren Randbits;)
Ich würde diesen Ansatz wahrscheinlich nie im Produktionscode verwenden, wenn ich meine Mitarbeiter nicht wirklich mochte.
edit: aktualisiert, um der Frage zu entsprechen (nur Großbuchstaben und Ziffern), und verwende bitweise Operatoren & und >> anstelle von% und //
quelle
Ich würde es so machen:
Oder nur:
quelle
Verwenden Sie die Funktion random.choice () von Numpy
Die Dokumentation finden Sie hier http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.random.choice.html
quelle
Manchmal können 0 (Null) & O (Buchstabe O) verwirrend sein. Also benutze ich
quelle
Die folgende Logik generiert immer noch eine Zufallsstichprobe mit 6 Zeichen
Keine Notwendigkeit, mit 6 zu multiplizieren
quelle
Für diejenigen unter Ihnen, die funktionale Python mögen:
Es generiert einen unbestimmten [unendlichen] Iterator aus verbundenen zufälligen Sequenzen, indem es zuerst eine unbestimmte Sequenz zufällig ausgewählter Symbole aus dem Spendenpool generiert und diese Sequenz dann in Längenteile aufteilt, die dann verbunden werden. Es sollte mit jeder Sequenz funktionieren, die getitem unterstützt Standardmäßig wird einfach eine zufällige Folge von alphanumerischen Buchstaben generiert, die Sie jedoch leicht ändern können, um andere Dinge zu generieren:
Zum Beispiel, um zufällige Ziffern-Tupel zu generieren:
Wenn Sie next nicht für die Generierung verwenden möchten, können Sie es einfach aufrufbar machen:
Wenn Sie die Sequenz im laufenden Betrieb generieren möchten, setzen Sie einfach join auf identity.
Wie andere bereits erwähnt haben, stellen Sie die entsprechende Auswahlfunktion ein, wenn Sie mehr Sicherheit benötigen:
Die Standardauswahl ist
choice
, dass das gleiche Symbol für jeden Block mehrmals ausgewählt werden kann. Wenn Sie stattdessen möchten, dass dasselbe Mitglied höchstens einmal für jeden Block ausgewählt wird, gibt es eine mögliche Verwendung:Wir verwenden
sample
als unseren Selektor, um die vollständige Auswahl zu treffen, sodass die Chunks tatsächlich die Länge 1 haben, und um zu verbinden, rufen wir einfach auf,next
welcher den nächsten vollständig generierten Chunk abruft, vorausgesetzt, dieses Beispiel scheint etwas umständlich und es ist ...quelle
(1) Dies gibt Ihnen alle Großbuchstaben und Zahlen:
(2) Wenn Sie später Kleinbuchstaben in Ihren Schlüssel aufnehmen möchten, funktioniert dies auch:
quelle
Dies ist eine Interpretation von Anurag Uniyals Antwort und etwas, an dem ich selbst gearbeitet habe.
quelle
Die
random.choice
Funktion wählt einen zufälligen Eintrag in einer Liste aus. Sie erstellen auch eine Liste, damit Sie das Zeichen in diefor
Anweisung einfügen können . Am Ende ist str ['t', 'm', '2', 'J', 'U', 'Q', '0', '4', 'C', 'K'], aber diestr = "".join(str)
Takes kümmere dich darum und lasse dich bei'tm2JUQ04CK'
.Hoffe das hilft!
quelle
range(num)
stattdessen verwenden können, und str hätte eine Zeichenfolge sein könnenstr += random.choice(chars)
.quelle
Hier kann die Länge des Strings für die Schleife geändert werden, dh für i im Bereich (1, Länge). Es ist ein einfacher Algorithmus, der leicht zu verstehen ist. Es verwendet eine Liste, damit Sie nicht benötigte Zeichen verwerfen können.
quelle
Ein einfaches:
quelle
Ich möchte Ihnen die nächste Option vorschlagen:
Paranoischer Modus:
quelle
Zwei Methoden:
Ausgabe :
Die Leistung der ersten Methode ist besser.
quelle
Ich habe fast alle Antworten durchgesehen, aber keine davon sieht einfacher aus. Ich würde Ihnen empfehlen, die Passgen- Bibliothek auszuprobieren, mit der im Allgemeinen zufällige Passwörter erstellt werden.
Sie können zufällige Zeichenfolgen Ihrer Wahl aus Länge, Interpunktion, Ziffern, Buchstaben und Groß- / Kleinschreibung generieren .
Hier ist der Code für Ihren Fall:
quelle
Generieren Sie eine zufällige 16-Byte-ID mit Buchstaben, Ziffern, '_' und '-'
os.urandom(16).translate((f'{string.ascii_letters}{string.digits}-_'*4).encode('ascii'))
quelle
Ich sah mir die verschiedenen Antworten an und nahm mir Zeit, um die Dokumentation der Geheimnisse zu lesen
Wenn ich mir genauer anschaue, was es zu bieten hat, habe ich eine sehr praktische Funktion gefunden, wenn Sie eine ID wie Google Drive IDs nachahmen möchten:
Verwenden Sie es folgendermaßen:
Geben Sie eine ID mit einer Länge von 32 Zeichen aus:
Ich weiß, dass dies etwas anders ist als die Frage des OP, aber ich gehe davon aus, dass es für viele, die nach dem gleichen Anwendungsfall suchten, den ich gesucht habe, immer noch hilfreich sein wird.
quelle
quelle
Ich fand das einfacher und sauberer.
Ändern Sie einfach die 64, um die Länge zu variieren, und ändern Sie den CharacterPool, um nur Alpha-Zahlen oder nur Zahlen oder seltsame Zeichen oder was auch immer Sie wollen.
quelle