mot - tuto random python




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

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

Si les UUID vous conviennent, utilisez le paquetage uuid intégré.

Une solution en ligne

import uuid; str(uuid.uuid4().get_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

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 de manière pythonic ?


(1) Cela vous donnera toutes les majuscules et les chiffres:

import string, random
passkey=''
for x in range(8):
    if random.choice([1,2]) == 1:
        passkey += passkey.join(random.choice(string.ascii_uppercase))
    else:
        passkey += passkey.join(random.choice(string.digits))
print passkey 

(2) Si vous souhaitez par la suite inclure des lettres minuscules dans votre clé, cela fonctionnera également:

import string, random
passkey=''
for x in range(8):
    if random.choice([1,2]) == 1:
        passkey += passkey.join(random.choice(string.ascii_letters))
    else:
        passkey += passkey.join(random.choice(string.digits))
print passkey  

Basé sur une autre réponse de dépassement de pile, La 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.


Ce quesion est le meilleur résultat actuel de Google 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. Utiliser random.choice au lieu de random.SystemRandom().choice dans une application qui nécessite une PRNG sécurisée pourrait être potentiellement dévastateur, et étant donné la popularité de cette question, je parie que cette erreur a déjà été faite plusieurs fois.

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

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

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


J'ai trouvé que c'était plus simple et plus propre.

str_Key           = ""
str_FullKey       = "" 
str_CharacterPool = "01234ABCDEFfghij~>()"
for int_I in range(64): 
    str_Key = random.choice(str_CharacterPool) 
    str_FullKey = str_FullKey + str_Key 

Changez juste le 64 pour varier la longueur, variez le CharacterPool pour faire alpha seulement alphanumérique ou numérique seulement ou caractères étranges ou peu importe ce que vous voulez.


Je le ferais de cette façon:

import random
from string import digits, ascii_uppercase

legals = digits + ascii_uppercase

def rand_string(length, char_set=legals):

    output = ''
    for _ in range(length): output += random.choice(char_set)
    return output

Ou juste:

def rand_string(length, char_set=legals):

    return ''.join( random.choice(char_set) for _ in range(length) )

Je voudrais vous suggérer la prochaine option:

import crypt
n = 10
crypt.crypt("any sring").replace('/', '').replace('.', '').upper()[-n:-1]

Mode paranoïaque:

import uuid
import crypt
n = 10
crypt.crypt(str(uuid.uuid4())).replace('/', '').replace('.', '').upper()[-n:-1]

Pour ceux d'entre vous qui aiment le python fonctionnel:

from itertools import imap, starmap, islice, repeat
from functools import partial
from string import letters, digits, join
from random import choice

join_chars = partial(join, sep='')
identity = lambda o: o

def irand_seqs(symbols=join_chars((letters, digits)), length=6, join=join_chars, select=choice, breakup=islice):
    """ Generates an indefinite sequence of joined random symbols each of a specific length
    :param symbols: symbols to select,
        [defaults to string.letters + string.digits, digits 0 - 9, lower and upper case English letters.]
    :param length: the length of each sequence,
        [defaults to 6]
    :param join: method used to join selected symbol, 
        [defaults to ''.join generating a string.]
    :param select: method used to select a random element from the giving population. 
        [defaults to random.choice, which selects a single element randomly]
    :return: indefinite iterator generating random sequences of giving [:param length]
    >>> from tools import irand_seqs
    >>> strings = irand_seqs()
    >>> a = next(strings)
    >>> assert isinstance(a, (str, unicode))
    >>> assert len(a) == 6
    >>> assert next(strings) != next(strings)
    """
    return imap(join, starmap(breakup, repeat((imap(select, repeat(symbols)), None, length))))

Il génère un itérateur indéfini [infini] de séquences aléatoires jointes, en générant d'abord une séquence indéfinie de symboles choisis aléatoirement dans le pool de don, puis en décomposant cette séquence en parties de longueur qui est ensuite jointe, cela devrait fonctionner avec n'importe quelle séquence supportant getitem , par défaut, il génère simplement une séquence aléatoire de lettres alphanumériques, bien que vous puissiez facilement modifier pour générer d'autres choses:

par exemple pour générer des tuples aléatoires de chiffres:

>>> irand_tuples = irand_seqs(xrange(10), join=tuple)
>>> next(irand_tuples)
(0, 5, 5, 7, 2, 8)
>>> next(irand_tuples)
(3, 2, 2, 0, 3, 1)

Si vous ne voulez pas utiliser next pour la génération, vous pouvez simplement la rendre appelable:

>>> irand_tuples = irand_seqs(xrange(10), join=tuple)
>>> make_rand_tuples = partial(next, irand_tuples) 
>>> make_rand_tuples()
(1, 6, 2, 8, 1, 9)

Si vous voulez générer la séquence à la volée, réglez simplement la jointure à l'identité.

>>> irand_tuples = irand_seqs(xrange(10), join=identity)
>>> selections = next(irand_tuples)
>>> next(selections)
8
>>> list(selections)
[6, 3, 8, 2, 2]

Comme d'autres l'ont mentionné, si vous avez besoin de plus de sécurité, définissez la fonction de sélection appropriée:

>>> from random import SystemRandom
>>> rand_strs = irand_seqs(select=SystemRandom().choice)
'QsaDxQ'

le sélecteur par défaut est le choice qui peut sélectionner le même symbole plusieurs fois pour chaque morceau, si à la place vous voulez que le même membre soit sélectionné au plus une fois pour chaque morceau puis, une utilisation possible:

>>> from random import sample
>>> irand_samples = irand_seqs(xrange(10), length=1, join=next, select=lambda pool: sample(pool, 6))
>>> next(irand_samples)
[0, 9, 2, 3, 1, 6]

on utilise sample comme notre sélecteur, pour faire la sélection complète, donc les morceaux sont en fait de longueur 1, et pour rejoindre on appelle simplement next ce qui récupère le morceau complètement généré suivant, cet exemple semble un peu encombrant et c'est ...


Si vous avez besoin d'une chaîne aléatoire plutôt que pseudo-aléatoire , vous devriez utiliser os.urandom comme 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))

Un simple:

import string
import random
character = string.lowercase + string.uppercase + string.digits + string.punctuation
char_len = len(character)
# you can specify your password length here
pass_len = random.randint(10,20)
password = ''
for x in range(pass_len):
    password = password + character[random.randint(0,char_len-1)]
print password

Une manière plus rapide, plus facile et plus flexible de le faire est d'utiliser le module strgen ( 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']

Garantir 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 d'une des 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.



c'est une réponse à la réponse d'Anurag Uniyal et quelque chose que je travaillais sur moi-même.

import random
import string

oneFile = open('‪Numbers.txt', 'w')
userInput = 0
key_count = 0
value_count = 0
chars = string.ascii_uppercase + string.digits + string.punctuation

for userInput in range(int(input('How many 12 digit keys do you want?'))):
    while key_count <= userInput:
        key_count += 1
        number = random.randint(1, 999)
        key = number

        text = str(key) + ": " + str(''.join(random.sample(chars*6, 12)))
        oneFile.write(text + "\n")
oneFile.close()

Deux méthodes:

import random, math

def randStr_1(chars:str, length:int) -> str:
    chars *= math.ceil(length / len(chars))
    chars = letters[0:length]
    chars = list(chars)
    random.shuffle(characters)

    return ''.join(chars)

def randStr_2(chars:str, length:int) -> str:
    return ''.join(random.choice(chars) for i in range(chars))


Référence :

from timeit import timeit

setup = """
import os, subprocess, time, string, random, math

def randStr_1(letters:str, length:int) -> str:
    letters *= math.ceil(length / len(letters))
    letters = letters[0:length]
    letters = list(letters)
    random.shuffle(letters)
    return ''.join(letters)

def randStr_2(letters:str, length:int) -> str:
    return ''.join(random.choice(letters) for i in range(length))
"""

print('Method 1 vs Method 2', ', run 10 times each.')

for length in [100,1000,10000,50000,100000,500000,1000000]:
    print(length, 'characters:')

    eff1 = timeit("randStr_1(string.ascii_letters, {})".format(length), setup=setup, number=10)
    eff2 = timeit("randStr_2(string.ascii_letters, {})".format(length), setup=setup, number=10)
    print('\t{}s : {}s'.format(round(eff1, 6), round(eff2, 6)))
    print('\tratio = {} : {}\n'.format(eff1/eff1, round(eff2/eff1, 2)))

Sortie:

Method 1 vs Method 2 , run 10 times each.

100 characters:
    0.001411s : 0.00179s
    ratio = 1.0 : 1.27

1000 characters:
    0.013857s : 0.017603s
    ratio = 1.0 : 1.27

10000 characters:
    0.13426s : 0.151169s
    ratio = 1.0 : 1.13

50000 characters:
    0.709403s : 0.855136s
    ratio = 1.0 : 1.21

100000 characters:
    1.360735s : 1.674584s
    ratio = 1.0 : 1.23

500000 characters:
    6.754923s : 7.160508s
    ratio = 1.0 : 1.06

1000000 characters:
    11.232965s : 14.223914s
    ratio = 1.0 : 1.27

La performance de la première méthode est meilleure.


>>> import random
>>> str = []
>>> chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
>>> num = int(raw_input('How long do you want the string to be?  '))
How long do you want the string to be?  10
>>> for k in range(1, num+1):
...    str.append(random.choice(chars))
...
>>> str = "".join(str)
>>> str
'tm2JUQ04CK'

La fonction random.choice sélectionne une entrée aléatoire dans une liste. Vous créez également une liste afin que vous puissiez ajouter le caractère dans l'instruction for . A la fin str est ['t', 'm', '2', 'J', 'U', 'Q', '0', '4', 'C', 'K'], mais le str = "".join(str) prend soin de cela, vous laissant avec 'tm2JUQ04CK' .

J'espère que cela t'aides!


>>> import string 
>>> import random

la logique suivante génère encore 6 échantillons aléatoires de caractères

>>> print ''.join(random.sample((string.ascii_uppercase+string.digits),6))
JT7K3Q

Pas besoin de multiplier par 6

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

TK82HK

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'





random