web-dev-qa-db-fra.com

Chaînes aléatoires en Python 2.6 (Est-ce correct?)

J'ai essayé de trouver un moyen plus pythonique de générer une chaîne aléatoire dans python qui peut également évoluer. En général, je vois quelque chose de similaire à

''.join(random.choice(string.letters) for i in xrange(len))

Cela craint si vous voulez générer une longue chaîne.

Je réfléchis à random.getrandombits depuis un certain temps, et j'ai trouvé comment convertir cela en un tableau de bits, puis l'encoder en hexadécimal. En utilisant python 2.6 je suis tombé sur l'objet bitarray, qui n'est pas documenté. D'une manière ou d'une autre, je l'ai fait fonctionner, et il semble vraiment rapide.

Il génère une chaîne aléatoire de 50mil sur mon ordinateur portable en seulement 3 secondes.

def Rand1(leng):
    nbits = leng * 6 + 1
    bits = random.getrandbits(nbits)
    uc = u"%0x" % bits
    newlen = int(len(uc) / 2) * 2 # we have to make the string an even length
    ba = bytearray.fromhex(uc[:newlen])
    return base64.urlsafe_b64encode(str(ba))[:leng]

modifier

heikogerlach a souligné que c'était un nombre impair de caractères à l'origine du problème. Nouveau code ajouté pour s'assurer qu'il envoie toujours depuis hex un nombre pair de chiffres hexadécimaux.

Toujours curieux de savoir s'il existe une meilleure façon de procéder, tout aussi rapide.

77
mikelikespie
import os
random_string = os.urandom(string_length)

et si vous avez besoin d'une chaîne sécurisée pour les URL:

import os
random_string = os.urandom(string_length).hex() 

(notez que la longueur de chaîne aléatoire est supérieure à la longueur de chaîne dans ce cas)

130
Seun Osewa

Parfois, un uuid est assez court et si vous n'aimez pas les tirets, vous pouvez toujours les remplacer ('-', '')

from uuid import uuid4

random_string = str(uuid4())

Si vous voulez une longueur spécifique sans tirets

random_string_length = 16
str(uuid4()).replace('-', '')[:random_string_length]
10
Joelbitar

Extrait du rapport de bogue 102329 sur Python.org:

junk_len = 1024
junk =  (("%%0%dX" % junk_len) % random.getrandbits(junk_len *
8)).decode("hex")

Consultez également les problèmes 92364 et 102329

6
fdr

Il semble que la méthode fromhex() attend un nombre pair de chiffres hexadécimaux. Votre chaîne contient 75 caractères. Soit conscient que something[:-1]exclut le dernier élément! Utilisez simplement something[:].

2
unbeknown

Concernant le dernier exemple, le correctif suivant pour s'assurer que la ligne est de longueur paire, quelle que soit la valeur junk_len:

junk_len = 1024
junk =  (("%%0%dX" % (junk_len * 2)) % random.getrandbits(junk_len * 8)).decode("hex")
2
user115995