Pregunta Generación de cadenas aleatorias con letras mayúsculas y dígitos en Python


Quiero generar una cadena de tamaño N.

Debe estar compuesto por números y letras mayúsculas en inglés, como:

  • 6U1S75
  • 4Z4UKK
  • U911K4

¿Cómo puedo lograr esto en una pitónico ¿camino?


997
2018-02-13 12:23


origen


Respuestas:


Responda en una línea:

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

o incluso más corto comenzando con Python 3.6 utilizando random.choices():

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

Una versión criptográficamente más segura; ver https://stackoverflow.com/a/23728630/2213647:

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

En detalles, con una función limpia para su posterior reutilización:

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

Como funciona ?

Importamos string, un módulo que contiene secuencias de caracteres ASCII comunes, y random, un módulo que trata con la generación aleatoria.

string.ascii_uppercase + string.digits simplemente concatena la lista de caracteres que representan mayúsculas y caracteres ASCII en mayúsculas:

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

Luego usamos una lista de comprensión para crear una lista de 'n' elementos:

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

En el ejemplo anterior, usamos [ para crear la lista, pero no en el id_generator función para que Python no cree la lista en la memoria, pero genera los elementos sobre la marcha, uno por uno (más sobre esto aquí)

En lugar de pedir crear 'n' veces la cadena elem, le pediremos a Python que cree 'n' veces un carácter aleatorio, elegido de una secuencia de caracteres:

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

Por lo tanto random.choice(chars) for _ in range(size) realmente está creando una secuencia de size caracteres. Caracteres que se seleccionan al azar de 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']

Luego solo los unimos con una cadena vacía para que la secuencia se convierta en una cadena:

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



Esta apuesta de desbordamiento de pila es el resultado actual superior de Google para "cadena aleatoria Python". La respuesta actual superior es:

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

Este es un método excelente, pero el PRNG al azar no es criptográficamente seguro. Supongo que mucha gente que investiga esta pregunta querrá generar cadenas aleatorias para encriptación o contraseñas. Puede hacerlo de manera segura haciendo un pequeño cambio en el código anterior:

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

Utilizando random.SystemRandom() en lugar de solo usos aleatorios / dev / urandom en máquinas * nix y CryptGenRandom() en Windows. Estos son PRNG criptográficamente seguros. Utilizando random.choice en lugar de random.SystemRandom().choice en una aplicación que requiere un PRNG seguro podría ser potencialmente devastador, y dada la popularidad de esta pregunta, apuesto a que el error ya se ha cometido muchas veces.

Si está usando python3.6 o superior, puede usar el nuevo misterios módulo.

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

Los documentos del módulo también discuten formas convenientes de generar tokens seguros y mejores prácticas.


448
2018-05-19 01:41



Simplemente use el uuid incorporado de Python:

Si los UUID están bien para sus propósitos, use el built-in uuid paquete.

Solución de una línea:

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

Versión en profundidad:

Ejemplo:

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

Si necesita exactamente su formato (por ejemplo, "6U1S75"), puede hacerlo así:

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



Una manera más simple, más rápida pero un poco menos aleatoria es usar random.sample en lugar de elegir cada letra por separado, si se permiten n-repeticiones, amplíe su base aleatoria n veces, p. ej.

import random
import string

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

Nota: random.sample evita la reutilización de caracteres, multiplicar el tamaño del conjunto de caracteres hace posible múltiples repeticiones, pero aún son menos probables, entonces están en una elección puramente aleatoria. Si buscamos una cadena de longitud 6, y elegimos 'X' como primer personaje, en el ejemplo de elección, las probabilidades de obtener 'X' para el segundo carácter son las mismas que las probabilidades de obtener 'X' como el primer personaje. En la implementación de random.sample, las probabilidades de obtener 'X' como cualquier personaje posterior son solo 6/7, la posibilidad de obtenerlo como el primer personaje


41
2018-02-13 12:44



import uuid
lowercase_str = uuid.uuid4().hex  

lowercase_str es un valor aleatorio como 'cea8b32e00934aaea8c005a35d85a5c0'

uppercase_str = lowercase_str.upper()

uppercase_str es 'CEA8B32E00934AAEA8C005A35D85A5C0'


22
2017-12-01 10:04



Tomando la respuesta de Ignacio, esto funciona con Python 2.6:

import random
import string

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

Ejemplo de salida:

JQUBT2


18
2018-02-13 12:35



Una forma más rápida, fácil y flexible de hacer esto es usar el strgen módulo (pip install StringGenerator)

Genere una cadena aleatoria de 6 caracteres con letras mayúsculas y dígitos:

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

Obtenga una lista única:

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

Garantía un personaje "especial" en la cadena:

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

Un color HTML aleatorio:

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

etc.

Debemos ser conscientes de esto:

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

podría no tener un dígito (o mayúscula) en él.

strgen es más rápido en tiempo de desarrollador que cualquiera de las soluciones anteriores. La solución de Ignacio es la ejecución más rápida en tiempo de ejecución y es la respuesta correcta utilizando Python Standard Library. Pero casi nunca lo usarás en esa forma. Querrá usar SystemRandom (o fallback si no está disponible), asegurarse de que se representen los juegos de caracteres necesarios, usar unicode (o no), asegurarse de que las invocaciones sucesivas produzcan una cadena única, usar un subconjunto de una de las clases de caracteres del módulo de cadena, etc. Todo esto requiere mucho más código que en las respuestas proporcionadas. Los diversos intentos de generalizar una solución tienen limitaciones que Strgen resuelve con mayor brevedad y poder expresivo usando un lenguaje de plantilla simple.

Está en PyPI:

pip install StringGenerator

Divulgación: soy el autor del módulo strgen.


16
2017-08-26 11:47