Zufällige Zeichenfolgengenerierung mit Großbuchstaben und Ziffern

Lesezeit: 8 Minuten

Benutzer-Avatar
Hellnar

Wie erzeuge ich eine Zeichenfolge der Größe N aus Zahlen und englischen Großbuchstaben wie:

  • 6U1S75
  • 4Z4UKK
  • U911K4

  • Dies ist eine sehr beliebte Frage. Ich wünschte, ein Experte würde seine Meinung zur Eindeutigkeit dieser Zufallszahlen für die Top-3-Antworten hinzufügen, dh die Kollisionswahrscheinlichkeit für den Bereich der Zeichenfolgengröße, sagen wir von 6 bis 16.

    – Benutzer

    21. Juni 2014 um 7:06 Uhr

  • @buffer Es ist einfach, die Anzahl der möglichen Kombinationen zu berechnen. 10 Zahlen + 26 Buchstaben = 36 mögliche Zeichen, hoch 6 (Länge der Zeichenfolge) entspricht etwa zwei Milliarden. Meine Faustregel für zufällige Werte lautet: “Wenn ich Werte für jeden Menschen auf der Erde generieren würde, wie viele Werte könnten sie jeweils haben?”. In diesem Fall wäre das weniger als ein Wert pro Person, wenn also Benutzer oder Objekte identifiziert werden sollen, sind es zu wenige Zeichen. Eine Alternative wäre, Kleinbuchstaben hinzuzufügen, was Sie bei 62 ^ 6 = fast 57 Milliarden eindeutigen Werten landet.

    – Blixt

    17. Mai 2015 um 18:17 Uhr

  • Und obwohl es albern erscheinen mag, an die Weltbevölkerung zu denken, liegt das nur daran, dass Sie einen riesigen Puffer für potenzielle Kollisionen haben möchten. Siehe das Geburtstagsproblem: en.wikipedia.org/wiki/Birthday_problem

    – Blixt

    17. Mai 2015 um 18:18 Uhr

  • @buffer, diese Antwort würde dich dann interessieren.

    – Anish Ramaswamy

    20. August 2015 um 2:09 Uhr

  • Sollte das nicht umbenannt werden “Kryptografisch sichere Generierung zufälliger Zeichenfolgen …”?

    – smci

    9. September 2018 um 1:09 Uhr


Benutzer-Avatar
Randy Marsch

Diese Stack Overflow-Frage ist das aktuelle Top-Google-Ergebnis für “Random String Python”. Die aktuelle Top-Antwort lautet:

''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))

Dies ist eine ausgezeichnete Methode, aber die PRNG in random ist nicht kryptografisch sicher. Ich nehme an, 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 eine kleine Änderung im obigen Code vornehmen:

''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))

Verwenden random.SystemRandom() statt nur zufällig verwendet /dev/urandom auf *nix-Rechnern und CryptGenRandom() unter Windows. Dies sind kryptografisch sichere PRNGs. Verwenden random.choice Anstatt von random.SystemRandom().choice in einer Anwendung, die ein sicheres PRNG erfordert, könnte möglicherweise verheerend sein, und angesichts der Popularität dieser Frage wette ich, dass dieser Fehler bereits viele Male gemacht wurde.

Wenn Sie Python 3.6 oder höher verwenden, können Sie die neue verwenden Geheimnisse Modul wie in MSeiferts Antwort erwähnt:

''.join(secrets.choice(string.ascii_uppercase + string.digits) for _ in range(N))

Die Moduldokumentation erörtert auch bequeme Möglichkeiten, um sichere Token generieren und empfohlene Vorgehensweise.

  • Ja, die offizielle Standardbibliothek für random hat dies gewarnt: “Warnung: Die Pseudozufallsgeneratoren dieses Moduls sollten nicht für Sicherheitszwecke verwendet werden. Verwenden Sie os.urandom() oder SystemRandom, wenn Sie einen kryptografisch sicheren Pseudozufallszahlengenerator benötigen.” Hier ist die Referenz: random.SystemRandom und os.urandom

    – Herr63. j

    16. Mai 2015 um 14:30 Uhr


  • Gute Antwort. Kleine Anmerkung: Sie haben es geändert in string.uppercase was je nach Gebietsschema zu unerwarteten Ergebnissen führen kann. Verwenden string.ascii_uppercase (oder string.ascii_letters + string.digits für base62 statt base36) ist sicherer, wenn es um Codierung geht.

    – Blixt

    17. Mai 2015 um 18:03 Uhr

  • kleine Anmerkung – besser zu verwenden xrange Anstatt von range da letzteres eine In-Memory-Liste generiert, während ersteres einen Iterator erstellt.

    – Kerl

    31. Juli 2016 um 11:44 Uhr

  • Wird der zufällige Stich immer einzigartig sein? Ich wollte einen Primärschlüssel verwenden.

    – Shakthydoss

    27. September 2016 um 8:45 Uhr

  • @shakthydoss: nein. Es kann “AAA000” zurückgeben, was eine zufällige Zeichenfolge ist, und als nächstes “AAA000”, was eine ist Auch eine zufällige Zeichenfolge. Sie müssen explizit eine Prüfung auf Eindeutigkeit hinzufügen.

    – Jongware

    2. März 2018 um 11:15 Uhr

  • +1 Für das Nachdenken hinter der Frage. Vielleicht könnten Sie kurz den Unterschied zwischen uuid1 und uuid4 erklären.

    – Thomas Ahle

    29. Januar 2014 um 12:36 Uhr


  • uui1: Generieren Sie eine UUID aus einer Host-ID, einer Sequenznummer und der aktuellen Uhrzeit. uuid4: Generiert eine zufällige UUID.

    – Bijan

    14. März 2014 um 5:19 Uhr

  • Wenn Sie das Casting und Ersetzen von Bindestrichen überspringen möchten, können Sie einfach my_uuid.get_hex() oder uuid.uuid4().get_hex() aufrufen und es wird eine aus der uuid generierte Zeichenfolge ohne Bindestriche zurückgegeben.

    – dshap

    11. April 2014 um 0:50 Uhr


  • Ist es eine gute Idee, eine UUID zu kürzen? Je nachdem wie klein string_length Das heißt, die Wahrscheinlichkeit einer Kollision kann ein Problem sein.

    – Benutzer

    21. Juni 2014 um 7:01 Uhr

  • Warum sich darauf beschränken nur Hex-Zeichen. Base64 oder Base32 (nur für Großbuchstaben und 6 verschiedene Ziffern), um einen Zufallscode zu codieren os.urandom() Bytes-Sequenz. Umgehen Sie die uuid Zwischenhändler für mehr Geschwindigkeit!

    – Martijn Pieters

    24. Januar 2018 um 13:39 Uhr

Benutzer-Avatar
Anurag Uniyal

Eine einfachere, schnellere, aber etwas weniger zufällige Methode ist die Verwendung random.sample Anstatt jeden Buchstaben einzeln auszuwählen, Wenn n-Wiederholungen erlaubt sind, vergrößern Sie Ihre Zufallsbasis um das n-fache, z

import random
import string

char_set = string.ascii_uppercase + string.digits
print ''.join(random.sample(char_set*6, 6))

Hinweis: random.sample verhindert die Wiederverwendung von Zeichen, die Vervielfachung der Größe des Zeichensatzes macht mehrere Wiederholungen möglich, aber sie sind immer noch weniger wahrscheinlich als bei einer rein zufälligen Auswahl. Wenn wir uns für eine Zeichenfolge der Länge 6 entscheiden und „X“ als erstes Zeichen auswählen, sind die Chancen, „X“ für das zweite Zeichen zu erhalten, im Auswahlbeispiel die gleichen wie die Chancen, „X“ als das zu erhalten erstes Zeichen. In der random.sample-Implementierung beträgt die Chance, „X“ als nachfolgendes Zeichen zu erhalten, nur 6/7 der Chance, es als erstes Zeichen zu erhalten

  • Das ist nicht schlecht, aber nicht ganz so zufällig, wie wenn man jedes Zeichen separat auswählt, wie bei sample Sie werden niemals denselben Charakter zweimal aufgelistet bekommen. Auch natürlich wird es scheitern N höher als 36.

    – Bobin

    13. Februar 2010 um 12:54 Uhr

  • Für den gegebenen Anwendungsfall (wenn keine Wiederholung in Ordnung ist) werde ich sagen, dass es immer noch die beste Lösung ist.

    – Anurag Uniyal

    13. Februar 2010 um 14:30 Uhr

  • Eines der Beispiele hat eine Wiederholung, also bezweifle ich, dass er versucht, Wiederholungen zu verbieten.

    – Mark Byers

    13. Februar 2010 um 14:34 Uhr

  • Wenn random.sample die Wiederverwendung von Zeichen verhindert, führt die Multiplikation der Größe des Zeichensatzes zu mehreren Wiederholungen möglichaber es sind noch weniger wahrscheinlich dann sind sie in einer rein zufälligen Auswahl. Wenn wir uns für eine Zeichenfolge der Länge 6 entscheiden und „X“ als erstes Zeichen auswählen, sind die Chancen, „X“ für das zweite Zeichen zu erhalten, im Auswahlbeispiel die gleichen wie die Chancen, „X“ als das zu erhalten erstes Zeichen. In der random.sample-Implementierung beträgt die Chance, „X“ als nachfolgendes Zeichen zu erhalten, nur 5/6 der Chance, es als erstes Zeichen zu erhalten.

    – pcurry

    31. August 2013 um 19:11 Uhr

  • Die Wahrscheinlichkeit, dass ein bestimmtes Zeichen wiederholt wird, sinkt, wenn Sie sich durch die generierte Zeichenfolge bewegen. Durch Generieren einer Zeichenfolge von 6 Zeichen aus den 26 Großbuchstaben plus 10 Ziffern, wobei jedes Zeichen zufällig unabhängig ausgewählt wird, tritt jede bestimmte Zeichenfolge mit der Häufigkeit 1 / (36 ^ 6) auf. Die Chance, „FU3WYE“ und „XXXXXX“ zu generieren, ist gleich. In der Beispielimplementierung beträgt die Chance, „XXXXXX“ zu generieren, (1/(36^6)) * ((6/6) * (5/6) * (4/6) * (3/6) * (2 /6) * (1/6)) aufgrund der Nicht-Ersetzungsfunktion von random.sample. „XXXXXX“ ist in der Beispielimplementierung 324-mal weniger wahrscheinlich.

    – pcurry

    31. August 2013 um 19:24 Uhr

Benutzer-Avatar
Jajo

import uuid
lowercase_str = uuid.uuid4().hex  

lowercase_str ist ein zufälliger Wert wie 'cea8b32e00934aaea8c005a35d85a5c0'

uppercase_str = lowercase_str.upper()

uppercase_str ist 'CEA8B32E00934AAEA8C005A35D85A5C0'

  • Das ist nicht schlecht, aber nicht ganz so zufällig, wie wenn man jedes Zeichen separat auswählt, wie bei sample Sie werden niemals denselben Charakter zweimal aufgelistet bekommen. Auch natürlich wird es scheitern N höher als 36.

    – Bobin

    13. Februar 2010 um 12:54 Uhr

  • Für den gegebenen Anwendungsfall (wenn keine Wiederholung in Ordnung ist) werde ich sagen, dass es immer noch die beste Lösung ist.

    – Anurag Uniyal

    13. Februar 2010 um 14:30 Uhr

  • Eines der Beispiele hat eine Wiederholung, also bezweifle ich, dass er versucht, Wiederholungen zu verbieten.

    – Mark Byers

    13. Februar 2010 um 14:34 Uhr

  • Wenn random.sample die Wiederverwendung von Zeichen verhindert, führt die Multiplikation der Größe des Zeichensatzes zu mehreren Wiederholungen möglichaber es sind noch weniger wahrscheinlich dann sind sie in einer rein zufälligen Auswahl. Wenn wir uns für eine Zeichenfolge der Länge 6 entscheiden und „X“ als erstes Zeichen auswählen, sind die Chancen, „X“ für das zweite Zeichen zu erhalten, im Auswahlbeispiel die gleichen wie die Chancen, „X“ als das zu erhalten erstes Zeichen. In der random.sample-Implementierung beträgt die Chance, „X“ als nachfolgendes Zeichen zu erhalten, nur 5/6 der Chance, es als erstes Zeichen zu erhalten.

    – pcurry

    31. August 2013 um 19:11 Uhr

  • Die Wahrscheinlichkeit, dass ein bestimmtes Zeichen wiederholt wird, sinkt, wenn Sie sich durch die generierte Zeichenfolge bewegen. Durch Generieren einer Zeichenfolge von 6 Zeichen aus den 26 Großbuchstaben plus 10 Ziffern, wobei jedes Zeichen zufällig unabhängig ausgewählt wird, tritt jede bestimmte Zeichenfolge mit der Häufigkeit 1 / (36 ^ 6) auf. Die Chance, „FU3WYE“ und „XXXXXX“ zu generieren, ist gleich. In der Beispielimplementierung beträgt die Chance, „XXXXXX“ zu generieren, (1/(36^6)) * ((6/6) * (5/6) * (4/6) * (3/6) * (2 /6) * (1/6)) aufgrund der Nicht-Ersetzungsfunktion von random.sample. „XXXXXX“ ist in der Beispielimplementierung 324-mal weniger wahrscheinlich.

    – pcurry

    31. August 2013 um 19:24 Uhr

Benutzer-Avatar
Brutus

Ab Python 3.6 sollten Sie die verwenden Geheimnis-Modul wenn Sie kryptografisch sicher sein müssen anstelle von random Modul (ansonsten ist diese Antwort identisch mit der von @Ignacio Vazquez-Abrams):

from secrets import choice
import string

''.join([choice(string.ascii_uppercase + string.digits) for _ in range(N)])

Eine zusätzliche Anmerkung: ein Listenverständnis ist schneller bei str.join als einen Generatorausdruck zu verwenden!

1158260cookie-checkZufällige Zeichenfolgengenerierung mit Großbuchstaben und Ziffern

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy