Je veux générer une chaîne de taille N.
Il doit être composé de chiffres et de lettres anglaises majuscules telles que:
- 6U1S75
- 4Z4UKK
- U911K4
Comment puis-je y parvenir de manière pythonique ?
Je veux générer une chaîne de taille N.
Il doit être composé de chiffres et de lettres anglaises majuscules telles que:
Comment puis-je y parvenir de manière pythonique ?
Réponses:
Répondez en une ligne:
ou encore plus court à partir de Python 3.6 en utilisant
random.choices()
:Une version cryptographiquement plus sécurisée; voir https://stackoverflow.com/a/23728630/2213647 :
En détail, avec une fonction propre pour une réutilisation ultérieure:
Comment ça marche ?
Nous importons
string
un module qui contient des séquences de caractères ASCII communs etrandom
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 et chiffres ASCII majuscules:Ensuite, nous utilisons une compréhension de liste pour créer une liste d'éléments 'n':
Dans l'exemple ci-dessus, nous utilisons
[
pour créer la liste, mais nous ne le faisons pas dans laid_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:C'est donc
random.choice(chars) for _ in range(size)
vraiment créer une séquence desize
personnages. Personnages choisis au hasard parmichars
:Ensuite, nous les rejoignons simplement avec une chaîne vide afin que la séquence devienne une chaîne:
la source
range
parxrange
.random
parrandom.SystemRandom()
: github.com/django/django/blob/…random.sample
crée des échantillons sans remplacement, en d'autres termes, sans possibilité de répéter les caractères, ce qui n'est pas dans les exigences de l'OP. Je ne pense pas que ce serait souhaitable pour la plupart des applications.Cette question de débordement de pile est le meilleur résultat Google actuel pour "chaîne aléatoire Python". La meilleure réponse actuelle est:
C'est une excellente méthode, mais le PRNG aléatoire n'est pas sécurisé cryptographiquement. Je suppose que de nombreuses personnes 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 effectuant une petite modification dans le code ci-dessus:
Utiliser
random.SystemRandom()
au lieu de simplement utiliser au hasard / dev / urandom sur les machines * nix etCryptGenRandom()
sous Windows. Ce sont des PRNG cryptographiquement sécurisés. Utiliserrandom.choice
au lieu derandom.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 cette erreur a déjà été commise plusieurs fois.Si vous utilisez python3.6 ou supérieur, vous pouvez utiliser le nouveau module secrets comme mentionné dans la réponse de MSeifert :
Les documents du module discutent également des moyens pratiques de générer des jetons sécurisés et des meilleures pratiques .
la source
random
a averti ceci: " Avertissement : Les générateurs pseudo-aléatoires de ce module ne doivent pas être utilisés à des fins de sécurité. Utilisez os.urandom () ou SystemRandom si vous avez besoin d'un générateur de nombres pseudo-aléatoires cryptographiquement sécurisé. " Voici la référence: random.SystemRandom et os.urandomstring.uppercase
qui peut entraîner des résultats inattendus en fonction de la configuration locale. L'utilisationstring.ascii_uppercase
(oustring.ascii_letters + string.digits
pour base62 au lieu de base36) est plus sûre dans les cas où l'encodage est impliqué.xrange
au lieu derange
car ce dernier génère une liste en mémoire, tandis que le premier crée un itérateur.Utilisez simplement l'uuid intégré de Python:
Si les UUID conviennent à vos besoins, utilisez le package uuid intégré.
Solution en une ligne:
import uuid; uuid.uuid4().hex.upper()[0:6]
Version détaillée:
Exemple:
Si vous avez besoin exactement de votre format (par exemple, "6U1S75"), vous pouvez le faire comme ceci:
la source
string_length
, la probabilité de collision peut être préoccupante.Une manière plus simple, plus rapide mais légèrement 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 exempleRemarque: random.sample empêche la réutilisation des caractères, la multiplication de la taille du jeu de caractères rend plusieurs répétitions possibles, mais elles sont encore moins probables qu'elles sont dans un pur choix aléatoire. Si nous optons pour 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 caractère. Dans l'implémentation random.sample, les chances d'obtenir «X» comme n'importe quel caractère suivant sont seulement 6/7 la chance de l'obtenir comme premier caractère
la source
sample
vous n'obtiendrez jamais le même personnage deux fois. Bien sûr, cela échoueraN
plus que36
.lowercase_str
est une valeur aléatoire comme'cea8b32e00934aaea8c005a35d85a5c0'
uppercase_str
est'CEA8B32E00934AAEA8C005A35D85A5C0'
la source
uppercase_str[:N+1]
Un moyen plus rapide, plus facile et plus flexible de le faire est d'utiliser le
strgen
module (pip install StringGenerator
).Générez une chaîne aléatoire de 6 caractères avec des lettres majuscules et des chiffres:
Obtenez une liste unique:
Garantissez un caractère "spécial" dans la chaîne:
Une couleur HTML aléatoire:
etc.
Nous devons être conscients que ceci:
peut ne pas contenir de chiffre (ou de caractère majuscule).
strgen
est plus rapide en temps de développement que n'importe laquelle des solutions ci-dessus. La solution d'Ignacio est l'exécution la plus rapide et constitue la bonne réponse en utilisant la bibliothèque standard Python. Mais vous ne l'utiliserez presque jamais sous cette forme. Vous souhaiterez utiliser SystemRandom (ou un repli s'il n'est pas 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 l'une des classes de caractères du module de chaîne, 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 une plus grande brièveté et une puissance expressive en utilisant un langage de modèle simple.C'est sur PyPI:
Divulgation: je suis l'auteur du module strgen.
la source
À partir de Python 3.6, vous devez utiliser le
secrets
module si vous avez besoin qu'il soit sécurisé cryptographiquement au lieu durandom
module (sinon cette réponse est identique à celle de @Ignacio Vazquez-Abrams):Une remarque supplémentaire: une compréhension de liste est plus rapide dans le cas
str.join
que l'utilisation d'une expression de générateur!la source
Basé sur une autre réponse Stack Overflow, le moyen le plus léger 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:
Plus vite.
la source
N
.Si vous avez besoin d'une chaîne aléatoire plutôt que pseudo aléatoire , vous devez utiliser
os.urandom
comme sourcela source
os.urandom
pas pseudo aléatoire? Il pourrait utiliser un meilleur algorithme pour générer des nombres plus aléatoires, mais il est toujours pseudo aléatoire./dev/random
et/dev/urandom
. Le problème est que les/dev/random
blocs quand il n'y a pas assez d'entropie ce qui limite son utilité. Pour un pad unique, ce/dev/urandom
n'est pas suffisant, mais je pense que c'est mieux que pseudo aléatoire ici./dev/random
et/dev/urandom
est pseudo aléatoire, mais cela pourrait dépendre de votre définition.Je pensais que personne n'avait encore répondu à ça lol! Mais bon, voici mon propre essai:
la source
Cette méthode est légèrement plus rapide et légèrement plus ennuyeuse que la méthode random.choice () publiée par Ignacio.
Il tire parti de la nature des algorithmes pseudo-aléatoires et mise sur les bits et les décalages plus rapidement que la génération d'un nouveau nombre aléatoire pour chaque caractère.
... créer un générateur qui supprime les nombres de 5 bits à la fois 0..31 jusqu'à ce qu'il n'en reste plus
... join () les résultats du générateur sur un nombre aléatoire avec les bons bits
Avec Timeit, pour les chaînes de 32 caractères, le timing était le suivant:
... mais pour 64 chaînes de caractères, les randbits perdent;)
Je n'utiliserais probablement jamais cette approche dans le code de production à moins que je n'aime vraiment pas mes collègues.
edit: mis à jour pour répondre à la question (majuscule et chiffres uniquement), et utilisez les opérateurs au niveau du bit & et >> au lieu de% et //
la source
Je le ferais de cette façon:
Ou juste:
la source
Utilisez la fonction random.choice () de Numpy
La documentation est ici http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.random.choice.html
la source
Parfois, 0 (zéro) et O (lettre O) peuvent prêter à confusion. J'utilise donc
la source
la logique suivante génère toujours un échantillon aléatoire de 6 caractères
Pas besoin de multiplier par 6
la source
Pour ceux d'entre vous qui aiment le python fonctionnel:
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 sélectionnés au hasard à partir du pool de donneurs, puis en divisant cette séquence en parties de longueur qui sont ensuite jointes, elle devrait fonctionner avec n'importe quelle séquence qui prend en charge getitem , par défaut, il génère simplement une séquence aléatoire de lettres alphanumériques, mais vous pouvez facilement modifier pour générer d'autres choses:
par exemple pour générer des tuples aléatoires de chiffres:
si vous ne voulez pas utiliser next pour la génération, vous pouvez simplement le rendre appelable:
si vous souhaitez générer la séquence à la volée, définissez simplement join sur identité.
Comme d'autres l'ont mentionné, si vous avez besoin de plus de sécurité, définissez la fonction de sélection appropriée:
le sélecteur par défaut est celui
choice
qui peut sélectionner le même symbole plusieurs fois pour chaque bloc, si au contraire vous souhaitez que le même membre soit sélectionné au plus une fois pour chaque bloc, alors, une utilisation possible:nous utilisons
sample
comme notre sélecteur, pour faire la sélection complète, donc les morceaux sont en fait de longueur 1, et pour rejoindre nous appelons simplementnext
qui récupère le prochain morceau complètement généré, étant donné que cet exemple semble un peu lourd et qu'il est ...la source
(1) Cela vous donnera tous les chiffres et majuscules:
(2) Si vous souhaitez plus tard inclure des lettres minuscules dans votre clé, cela fonctionnera également:
la source
c'est une prise sur la réponse d'Anurag Uniyal et quelque chose que je travaillais sur moi-même.
la source
La
random.choice
fonction sélectionne une entrée aléatoire dans une liste. Vous créez également une liste afin de pouvoir ajouter le caractère dans l'for
instruction. À la fin, str est ['t', 'm', '2', 'J', 'U', 'Q', '0', '4', 'C', 'K'], mais lesstr = "".join(str)
prises prendre soin de cela, vous laissant avec'tm2JUQ04CK'
.J'espère que cela t'aides!
la source
range(num)
place, et str aurait pu être une chaînestr += random.choice(chars)
.la source
Ici, la longueur de la chaîne peut être modifiée pour la boucle, c'est-à-dire pour i dans la plage (1, longueur). C'est un algorithme simple qui est facile à comprendre. il utilise la liste afin que vous puissiez éliminer les caractères dont vous n'avez pas besoin.
la source
Un simple:
la source
Je voudrais vous suggérer la prochaine option:
Mode paranoïaque:
la source
Deux méthodes:
Production :
Les performances de la première méthode sont meilleures.
la source
J'ai parcouru presque toutes les réponses, mais aucune ne semble plus facile. Je vous suggère d'essayer le passgen bibliothèque qui est généralement utilisée pour créer des mots de passe aléatoires.
Vous pouvez générer des chaînes aléatoires de votre choix de longueur, ponctuation, chiffres, lettres et casse.
Voici le code de votre cas:
la source
Générer un ID aléatoire de 16 octets contenant des lettres, des chiffres, «_» et «-»
os.urandom(16).translate((f'{string.ascii_letters}{string.digits}-_'*4).encode('ascii'))
la source
Je regardais les différentes réponses et pris le temps de lire la documentation des secrets
En examinant davantage ce qu'il a à offrir, j'ai trouvé une fonction très pratique si vous souhaitez imiter un identifiant comme les identifiants Google Drive:
Utilisez-le de la manière suivante:
Afficher un identifiant de longueur de 32 caractères:
Je sais que cela est légèrement différent de la question du PO, mais je m'attends à ce que cela soit toujours utile à beaucoup de ceux qui recherchaient le même cas d'utilisation que je cherchais.
la source
la source
J'ai trouvé que c'était plus simple et plus propre.
Modifiez simplement le 64 pour varier la longueur, faites varier le CharacterPool pour faire de l'alpha uniquement alphanumérique ou numérique uniquement ou des caractères étranges ou tout ce que vous voulez.
la source