web-dev-qa-db-fra.com

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

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

Quelque chose comme ce travail?

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

Quelle serait une bonne façon de générer des nombres aléatoires? Si je le fonde sur le microtime, je dois tenir compte de la possibilité de plusieurs appels de genKey () en même temps à partir d'instances différentes.

Ou existe-t-il une meilleure façon de faire tout cela?

51
ensnare

Comme aucune des réponses ne vous fournit une chaîne aléatoire composée des caractères 0-9, a-z, A-Z: Voici une solution de travail qui vous donnera une d'environ. 4.5231285 touches e + 74:

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 existe une version encore plus courte puisque python 3.6.2:

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

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, vous devez donc être prêt à réessayer avec une nouvelle clé en cas d'échec de l'insertion d'origine. En outre, vous voudrez peut-être envisager d'utiliser un algorithme déterministe pour générer une chaîne à partir d'un identifiant auto-incrémenté au lieu d'utiliser des valeurs aléatoires, car cela vous garantira l'unicité (mais cela donnera également des clés prévisibles).

46
Mark Byers

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 une longueur de 32 caractères. Vous ne devez pas tronquer cette chaîne, utilisez plutôt les 32 caractères complets.

32
ChristopheD

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]
6
rlotun

Dans Python 3.6, sorti en décembre 2016, le module secrets a été introduit.

Vous pouvez maintenant générer un jeton aléatoire de cette façon:

import secrets

secrets.token_hex(16)

Depuis les documents Python:

Le module secrets est utilisé pour générer des nombres aléatoires cryptographiquement solides adaptés à la gestion de données telles que les mots de passe, l'authentification de compte, les jetons de sécurité et les secrets associés.

En particulier, secrets doit être utilisé de préférence au générateur de nombres pseudo-aléatoires par défaut dans le module random, qui est conçu pour la modélisation et la simulation, pas pour la sécurité ou la cryptographie.

https://docs.python.org/3/library/secrets.html

6
Brachamul
>>> import random
>>> ''.join(random.sample(map(chr, range(48, 57) + range(65, 90) + range(97, 122)), 16))
'CDh0geq3NpKtcXfP'
3
yaccz

Cette valeur est incrémentée de 1 à chaque appel (elle s'enroule). Décider où le meilleur endroit pour stocker la valeur dépendra de la façon dont vous l'utilisez. Vous pouvez trouver cette explication d'intérêt, car elle explique non seulement comment les Guids fonctionnent, mais aussi comment en faire un plus petit.

La réponse courte est la suivante: utilisez certains de ces caractères comme horodatage et les autres caractères comme "uniquifier", une valeur incrémente de 1 à chaque appel à votre générateur uid.

2
Brian

utilisez simplement python intégré id:

import uuid
print uuid.uuid4().hex[:16].upper()
0
Chirag Maliwal