110 votes

Générez efficacement une chaîne alphanumérique de 16 caractères

Je cherche un moyen très rapide de générer un identifiant unique alphanumérique pour une clé primaire dans une table.

Quelque chose comme ça marcherait ?

def genKey():
    hash = hashlib.md5(RANDOM_NUMBER).digest().encode("base64")
    alnum_hash = re.sub(r'[^a-zA-Z0-9]', "", hash)
    return alnum_hash[:16]

Quel serait un bon moyen de générer des nombres aléatoires ? Si je le base sur microtime, je dois tenir compte de la possibilité de plusieurs appels de genKey () en même temps à partir de différentes instances.

Ou y a-t-il une meilleure façon de faire tout ça ?

186voto

David Nathan Points 2616

Comme aucune des réponses ne vous fournit une chaîne aléatoire composée de caractères 0-9, a-z, A-Z : Voici une solution de travail qui vous donnera l'une des touches env. 62^16 = 4.76724 e+28 :

import random, string
x = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(16))
print(x)

Il est également très lisible sans connaître les codes ASCII par cœur.

Il y a une version encore plus courte depuis python 3.6.2 :

import random, string
x = ''.join(random.choices(string.ascii_letters + string.digits, k=16))
print(x)

64voto

Mark Byers Points 318575

Vous pouvez utiliser ceci :

>>> import random
>>> ''.join(random.choice('0123456789ABCDEF') for i in range(16))
'E2C6B2E19E4A7777'

Il n'y a aucune garantie que les clés générées seront uniques de sorte que vous devriez être prêt à réessayer avec une nouvelle clé dans le cas où l'insert original échoue. En outre, vous pouvez envisager d'utiliser un algorithme déterministe pour générer une chaîne à partir d'un id auto-incrémenté au lieu d'utiliser des valeurs aléatoires, car cela vous garantira l'unicité (mais il donnera également des clés prévisibles).

42voto

ChristopheD Points 38217

Jetez un œil au module uuid (Python 2.5+).

Un exemple rapide :

>>> import uuid
>>> uid = uuid.uuid4()
>>> uid.hex
'df008b2e24f947b1b873c94d8a3f2201'

Notez que l'OP a demandé une chaîne alphanumérique de 16 caractères, mais les chaînes UUID4 ont 32 caractères. Vous ne devriez pas tronquer cette chaîne, au lieu de cela, utilisez les 32 caractères complets.

5voto

rlotun Points 3995

Pour les nombres aléatoires, une bonne source est os.urandom :

 >> import os
 >> import hashlib
 >> random_data = os.urandom(128)
 >> hashlib.md5(random_data).hexdigest()[:16]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X