Frage Zufällige String-Generierung mit Großbuchstaben und Ziffern in Python


Ich möchte eine Zeichenfolge der Größe N generieren.

Es sollte aus Zahlen und englischen Großbuchstaben bestehen wie:

  • 6U1S75
  • 4Z4UKK
  • U911K4

Wie erreiche ich das in einem pythonisch Weg?


997
2018-02-13 12:23


Ursprung


Antworten:


Antwort in einer Zeile:

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

oder noch kürzer beginnend mit Python 3.6 mit random.choices():

''.join(random.choices(string.ascii_uppercase + string.digits, k=N))

Eine kryptographisch sicherere Version; sehen https://stackoverflow.com/a/23728630/2213647:

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

Im Detail, mit einer sauberen Funktion für die weitere Wiederverwendung:

>>> import string
>>> import random
>>> def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
...    return ''.join(random.choice(chars) for _ in range(size))
...
>>> id_generator()
'G5G74W'
>>> id_generator(3, "6793YUIO")
'Y3U'

Wie funktioniert es ?

Wir importieren string, ein Modul, das Sequenzen von üblichen ASCII-Zeichen enthält, und randomein Modul, das sich mit zufälliger Generierung beschäftigt.

string.ascii_uppercase + string.digits Verkettet einfach die Liste von Zeichen, die ASCII-Zeichen und Ziffern in Großbuchstaben darstellen:

>>> string.ascii_uppercase
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.digits
'0123456789'
>>> string.ascii_uppercase + string.digits
'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'

Dann verwenden wir ein Listenverständnis, um eine Liste von 'n' Elementen zu erstellen:

>>> range(4) # range create a list of 'n' numbers
[0, 1, 2, 3]
>>> ['elem' for _ in range(4)] # we use range to create 4 times 'elem'
['elem', 'elem', 'elem', 'elem']

Im obigen Beispiel verwenden wir [ um die Liste zu erstellen, aber wir nicht in der id_generator Funktion, so dass Python die Liste nicht im Speicher erstellt, sondern die Elemente einzeln nacheinander generiert (mehr dazu) Hier).

Anstatt zu verlangen, n mal die Zeichenfolge zu erstellen elem, werden wir Python bitten, 'n' mal ein zufälliges Zeichen zu erstellen, das aus einer Abfolge von Zeichen ausgewählt wurde:

>>> random.choice("abcde")
'a'
>>> random.choice("abcde")
'd'
>>> random.choice("abcde")
'b'

Deshalb random.choice(chars) for _ in range(size) erstellt wirklich eine Sequenz von size Figuren. Zeichen, die zufällig ausgewählt werden chars:

>>> [random.choice('abcde') for _ in range(3)]
['a', 'b', 'b']
>>> [random.choice('abcde') for _ in range(3)]
['e', 'b', 'e']
>>> [random.choice('abcde') for _ in range(3)]
['d', 'a', 'c']

Dann verbinden wir sie einfach mit einer leeren Zeichenfolge, so dass die Sequenz zu einer Zeichenfolge wird:

>>> ''.join(['a', 'b', 'b'])
'abb'
>>> [random.choice('abcde') for _ in range(3)]
['d', 'c', 'b']
>>> ''.join(random.choice('abcde') for _ in range(3))
'dac'

2049
2018-02-13 12:26



Diese Stapelüberlauf-Frage ist das aktuelle Top-Google-Ergebnis für "zufällige Zeichenfolge 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 zufälliger Form ist nicht kryptographisch sicher. Ich nehme an, viele Leute, die diese Frage untersuchen, wollen zufällige Zeichenfolgen für die Verschlüsselung oder Passwörter erzeugen. 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ällige Anwendungen / Dev / Urandom auf * nix Maschinen und CryptGenRandom() in Windows. Dies sind kryptographisch sichere PRNGs. Verwenden random.choice Anstatt von random.SystemRandom().choice in einer Anwendung, die eine sichere PRNG erfordert, könnte potenziell verheerend sein, und angesichts der Popularität dieser Frage wette ich, dass dieser Fehler schon viele Male gemacht wurde.

Wenn Sie python3.6 oder höher verwenden, können Sie das neue verwenden Geheimnisse Modul.

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

Die Modul-Dokumente diskutieren auch bequeme Wege zu sichere Token generieren und Best Practices.


448
2018-05-19 01:41



Benutze einfach Pythons eingebaute Uuid:

Wenn UUIDs für Ihre Zwecke geeignet sind, verwenden Sie das integrierte Dienstprogramm Uuid Paket.

Einzellösung:

import uuid; uuid.uuid4().hex.upper()[0:6]

In der Tiefe Version:

Beispiel:

import uuid
uuid.uuid4() #uuid4 => full random uuid
# Outputs something like: UUID('0172fc9a-1dac-4414-b88d-6b9a6feb91ea')

Wenn Sie genau Ihr Format benötigen (zum Beispiel "6U1S75"), können Sie es so machen:

import uuid

def my_random_string(string_length=10):
    """Returns a random string of length string_length."""
    random = str(uuid.uuid4()) # Convert UUID format to a Python string.
    random = random.upper() # Make all characters uppercase.
    random = random.replace("-","") # Remove the UUID '-'.
    return random[0:string_length] # Return the random string.

print(my_random_string(6)) # For example, D9E50C

132
2018-06-26 15:11



Es ist einfacher, schneller, aber etwas weniger zufällig zu verwenden random.sample anstatt jeden Buchstaben einzeln zu wählen, wenn N-Wiederholungen erlaubt sind, vergrößern Sie Ihre Zufallsbasis um n-mal 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 Multiplikation der Größe des Zeichensatzes macht mehrere Wiederholungen möglich, aber sie sind immer noch weniger wahrscheinlich als bei einer reinen Zufallsauswahl. Wenn wir eine Zeichenfolge der Länge 6 wählen und als erstes Zeichen 'X' wählen, sind im Auswahlbeispiel die Chancen, 'X' für das zweite Zeichen zu erhalten, gleich der Wahrscheinlichkeit, 'X' zu erhalten erstes Zeichen In der random.sample-Implementation ist die Chance, 'X' als irgendein nachfolgendes Zeichen zu erhalten, nur 6/7 die Chance, es als das erste Zeichen zu erhalten


41
2018-02-13 12:44



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'


22
2017-12-01 10:04



Die Antwort von Ignacio funktioniert mit Python 2.6:

import random
import string

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

Beispielausgabe:

JQUBT2


18
2018-02-13 12:35



Eine schnellere, einfachere und flexiblere Methode ist die Verwendung der strgen Modul (pip install StringGenerator).

Generieren Sie eine zufällige 6-stellige Zeichenfolge mit Großbuchstaben und Ziffern:

>>> from strgen import StringGenerator as SG
>>> SG("[\u\d]{6}").render()
u'YZI2CI'

Erhalte eine einzigartige Liste:

>>> SG("[\l\d]{10}").render_list(5,unique=True)
[u'xqqtmi1pOk', u'zmkWdUr63O', u'PGaGcPHrX2', u'6RZiUbkk2i', u'j9eIeeWgEF']

Garantie ein "spezielles" Zeichen in der Zeichenfolge:

>>> SG("[\l\d]{10}&[\p]").render()
u'jaYI0bcPG*0'

Eine zufällige HTML-Farbe:

>>> SG("#[\h]{6}").render()
u'#CEdFCa'

etc.

Wir müssen uns bewusst sein, dass dies:

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

hat möglicherweise keine Ziffer (oder ein Großbuchstabe).

strgen ist schneller in der Entwicklerzeit als irgendeine der obigen Lösungen. Die Lösung von Ignacio ist die schnellste Laufzeit und ist die richtige Antwort mit der Python Standard Library. Aber Sie werden es in dieser Form kaum 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 aufeinander folgende Aufrufe eine eindeutige Zeichenfolge erzeugen, eine Teilmenge einer der String-Modul-Zeichenklassen verwenden. usw. Das alles erfordert viel mehr Code als in den Antworten zur Verfügung gestellt. Die verschiedenen Versuche, eine Lösung zu verallgemeinern, haben alle Beschränkungen, die strgen mit größerer Kürze und Ausdruckskraft unter Verwendung einer einfachen Template-Sprache löst.

Es ist auf PyPI:

pip install StringGenerator

Offenlegung: Ich bin der Autor des Strgen-Moduls.


16
2017-08-26 11:47