Question Génération de chaîne aléatoire avec des majuscules et des chiffres en Python


Je veux générer une chaîne de taille N.

Il devrait être composé de chiffres et de lettres anglaises majuscules telles que:

  • 6U1S75
  • 4Z4UKK
  • U911K4

Comment puis-je y parvenir dans un pythonique façon?


997
2018-02-13 12:23


origine


Réponses:


Répondez en une ligne:

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

ou même plus court à partir de Python 3.6 en utilisant random.choices():

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

Une version cryptographiquement plus sécurisée; voir https://stackoverflow.com/a/23728630/2213647:

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

En détails, avec une fonction propre pour une réutilisation ultérieure:

>>> 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'

Comment ça marche ?

Nous importons string, un module qui contient des séquences de caractères ASCII communs, et random, un module qui traite de la génération aléatoire.

string.ascii_uppercase + string.digits Concatène simplement la liste des caractères représentant les caractères ASCII majuscules et les chiffres:

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

Ensuite, nous utilisons une liste de compréhension pour créer une liste d'éléments 'n':

>>> 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']

Dans l'exemple ci-dessus, nous utilisons [ pour créer la liste, mais nous ne le faisons pas dans le id_generator fonction donc Python ne crée pas la liste en mémoire, mais génère les éléments à la volée, un par un (plus à ce sujet ici).

Au lieu de demander de créer 'n' fois la chaîne elem, nous demanderons à Python de créer 'n' fois un caractère aléatoire, choisi parmi une séquence de caractères:

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

Donc random.choice(chars) for _ in range(size) est vraiment la création d'une séquence de size personnages. Les caractères choisis au hasard dans 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']

Ensuite, nous les joignons simplement avec une chaîne vide pour que la séquence devienne une chaîne:

>>> ''.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



Ce quesion Stack Overflow est le meilleur résultat Google actuel pour "chaîne de caractères aléatoire Python". La meilleure réponse actuelle est:

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

C'est une excellente méthode, mais le PRNG au hasard n'est pas cryptographiquement sécurisé. Je suppose que beaucoup de gens recherchant cette question voudront générer des chaînes aléatoires pour le cryptage ou les mots de passe. Vous pouvez le faire en toute sécurité en faisant une petite modification dans le code ci-dessus:

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

En utilisant random.SystemRandom() au lieu de simplement utiliser au hasard / dev / urandom sur les machines * nix et CryptGenRandom() dans Windows Ce sont des PRNG cryptographiquement sécurisés. En utilisant random.choice au lieu de random.SystemRandom().choice dans une application qui nécessite un PRNG sécurisé pourrait être potentiellement dévastateur, et étant donné la popularité de cette question, je parie que l'erreur a été faite à plusieurs reprises déjà.

Si vous utilisez python3.6 ou supérieur, vous pouvez utiliser le nouveau secrets module.

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

Les docs de module discutent également des moyens pratiques de générer des jetons sécurisés et les meilleures pratiques.


448
2018-05-19 01:41



Utilisez simplement l'uuid intégré de Python:

Si les identificateurs UUID sont adaptés à vos besoins, utilisez le module intégré. uuid paquet.

Une solution en ligne

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

En profondeur Version:

Exemple:

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

Si vous avez besoin exactement de votre format (par exemple, "6U1S75"), vous pouvez le faire comme ceci:

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



Une manière plus simple, plus rapide mais un peu moins aléatoire consiste à utiliser random.sample Au lieu de choisir chaque lettre séparément, Si n-répétitions sont autorisées, agrandissez votre base aléatoire de n fois, par ex.

import random
import string

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

Remarque: random.sample empêche la réutilisation des caractères, multipliant la taille du jeu de caractères rend possible plusieurs répétitions, mais ils sont moins probables alors ils sont dans un choix aléatoire pur. Si nous choisissons une chaîne de longueur 6, et que nous choisissons 'X' comme premier caractère, dans l'exemple de choix, les chances d'obtenir 'X' pour le deuxième caractère sont les mêmes que les chances d'obtenir 'X' comme premier personnage. Dans l'implémentation random.sample, les chances d'obtenir 'X' comme n'importe quel caractère suivant ne sont que 6/7 la chance de l'obtenir comme premier caractère


41
2018-02-13 12:44



import uuid
lowercase_str = uuid.uuid4().hex  

lowercase_str est une valeur aléatoire comme 'cea8b32e00934aaea8c005a35d85a5c0'

uppercase_str = lowercase_str.upper()

uppercase_str est 'CEA8B32E00934AAEA8C005A35D85A5C0'


22
2017-12-01 10:04



Prenant la réponse d'Ignacio, cela fonctionne avec Python 2.6:

import random
import string

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

Exemple de sortie:

JQUBT2


18
2018-02-13 12:35



Un moyen plus rapide, plus facile et plus flexible de le faire est d'utiliser strgen module (pip install StringGenerator).

Générer une chaîne aléatoire de 6 caractères avec des majuscules et des chiffres:

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

Obtenez une liste unique:

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

Garantie un caractère "spécial" dans la chaîne:

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

Une couleur HTML aléatoire:

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

etc.

Nous devons être conscients que ceci:

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

peut ne pas avoir un chiffre (ou une majuscule) dedans.

strgen est plus rapide en temps de développement que n'importe laquelle des solutions ci-dessus. La solution d'Ignacio est la solution la plus rapide et la meilleure en utilisant la bibliothèque standard Python. Mais vous ne l'utiliserez presque jamais sous cette forme. Vous voudrez utiliser SystemRandom (ou fallback si non disponible), assurez-vous que les jeux de caractères requis sont représentés, utilisez unicode (ou non), assurez-vous que les invocations successives produisent une chaîne unique, utilisez un sous-ensemble de classes de caractères etc. Tout cela nécessite beaucoup plus de code que dans les réponses fournies. Les diverses tentatives de généralisation d'une solution ont toutes des limites que strgen résout avec plus de brièveté et de puissance expressive en utilisant un langage de template simple.

C'est sur PyPI:

pip install StringGenerator

Divulgation: Je suis l'auteur du module strgen.


16
2017-08-26 11:47



Si vous avez besoin d'une chaîne aléatoire plutôt que d'un pseudo aléatoire un, vous devriez utiliser os.urandom comme la source

from os import urandom
from itertools import islice, imap, repeat
import string

def rand_string(length=5):
    chars = set(string.ascii_uppercase + string.digits)
    char_gen = (c for c in imap(urandom, repeat(1)) if c in chars)
    return ''.join(islice(char_gen, None, length))

8
2017-09-13 04:32



Je pensais que personne n'avait encore répondu à cette question! Mais bon, voici mon propre coup d'oeil:

import random

def random_alphanumeric(limit):
    #ascii alphabet of all alphanumerals
    r = (range(48, 58) + range(65, 91) + range(97, 123))
    random.shuffle(r)
    return reduce(lambda i, s: i + chr(s), r[:random.randint(0, len(r))], "")

8
2018-02-10 23:27



Basé sur une autre réponse Stack Overflow, Façon la plus légère de créer une chaîne aléatoire et un nombre hexadécimal aléatoire, une meilleure version que la réponse acceptée serait:

('%06x' % random.randrange(16**6)).upper()

Plus vite.


8
2017-12-19 17:51