Losowe ciągi w Pythonie 2.6 (Czy to jest w porządku?)

Próbowałem znaleźć bardziej pythoniczny sposób generowania losowego ciągu w Pythonie, który może również skalować. Zazwyczaj widzę coś podobnego do

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

Jest do bani, jeśli chcesz wygenerować długi ciąg.

Myślałem o random.getrandombits przez jakiś czas, i zastanawiając się, jak przekonwertować to do tablicy bitów, a następnie hex zakodować to. Używając Pythona 2.6 natknąłem się na obiekt bitarray, który nie jest udokumentowany. Jakoś mi się udało i wydaje się, że naprawdę szybko.

Generuje 50mil losowy ciąg na moim notebooku w zaledwie 3 sekundy.

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]

Edit

Heikogerlach zauważył, że przyczyną problemu była Nieparzysta liczba znaków. Dodano nowy kod, aby upewnić się, że zawsze wysyłał fromhex parzystą liczbę cyfr szesnastkowych. Wciąż jestem ciekaw, czy jest lepszy sposób na zrobienie tego tak szybko.
Author: mikelikespie, 2009-04-24

5 answers

import os
random_string = os.urandom(string_length)

I jeśli potrzebujesz bezpiecznego ciągu URL:

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

(Uwaga Długość random_string jest największa niż długość string_length w tym przypadku)

 131
Author: Seun Osewa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-13 21:25:14

Czasami uuid jest wystarczająco krótki i jeśli nie lubisz kresek, zawsze możesz.replace (' - ' ,") them

from uuid import uuid4

random_string = str(uuid4())

Jeśli chcesz mieć określoną długość bez kresek

random_string_length = 16
str(uuid4()).replace('-', '')[:random_string_length]
 9
Author: Joelbitar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-26 12:59:27

Wzięte z 1023290 zgłoszenie błędu na Python.org:

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

Zobacz też 923643 oraz 1023290

 6
Author: fdr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-25 01:20:33

Wygląda na to, że metoda fromhex() oczekuje parzystej liczby cyfr szesnastkowych. Twój ciąg ma długość 75 znaków. Należy pamiętać, że something[:-1] wyłącza ostatni element! Wystarczy użyć something[:].

 2
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-24 09:09:45

Jeśli chodzi o ostatni przykład, następująca poprawka, aby upewnić się, że linia ma parzystą długość, niezależnie od wartości junk_len:

junk_len = 1024
junk =  (("%%0%dX" % (junk_len * 2)) % random.getrandbits(junk_len * 8)).decode("hex")
 2
Author: user115995,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-02 13:24:54