2009-04-24 2 views
77

Я пытаюсь найти более питоновский способ генерации случайной строки в python, который также может масштабироваться. Как правило, я вижу нечто похожее наСлучайные строки в Python 2.6 (это нормально?)

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

Это отстой, если вы хотите сгенерировать длинную строку.

Я некоторое время думал о random.getrandombits и выяснял, как преобразовать его в массив бит, а затем кодировать шестнадцатеричный код. Используя python 2.6, я столкнулся с объектом bitarray, который не документирован. Как-то я получил его на работу, и это кажется очень быстрым.

Он генерирует случайную строку длиной 50 мил на моем ноутбуке всего за 3 секунды.

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] 

редактировать

heikogerlach отметил, что это было нечетное количество символов, вызывающих проблему. Добавлен новый код, чтобы он всегда отправлял fromhex четное число шестнадцатеричных цифр.

По-прежнему любопытно, есть ли лучший способ сделать это так же быстро.

+1

Как сделать это так, что она будет включать только цифры, буквы, и нижнее подчеркивание? (Это включает тире) – wenbert

+2

@wenbert '.join (random.choice (string.letters + string.digits + "_") для i в xrange (length)) – yanjost

ответ

132
import os 
random_string = os.urandom(string_length) 

и если вам нужен URL-адрес безопасной строку:

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

(примечание длина random_string наибольшая чем string_length в этом случае)

+0

Ah! Так просто. Я не думал, что это кросс-платформенный, но, судя по всему, это так. – mikelikespie

+0

Простое наблюдение, это действительно странно, но по крайней мере на OS X метод getrandbits в 2-3 раза быстрее. – mikelikespie

+9

Это, вероятно, потому что os.urandom будет криптографически защищенным PRNG (обычно это потоковый шифр), тогда как случайный - это «нормальный» PRNG, который, как правило, быстрее вычисляется. – Joey

2

кажется метод fromhex() ожидает четное количество шестнадцатеричных цифр , Длина строки - 75 символов. Следует иметь в виду, что не включает Последний элемент! Просто используйте something[:].

+0

Существовал трейлинг L с __hex __(). Я переписал образец кода. В любом случае, я думаю, что вы были на этом праве, требуя четного числа цифр – mikelikespie

5

Взятого из доклада 1023290 ошибки в Python.org:

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

Кроме того, увидеть проблемы 923643 и 1023290

+0

+1, чтобы напомнить мне о кодировке hex. – Buttons840

2

Что касается последнего примера, следующие исправления, чтобы убедиться, что линия даже длина , независимо от значения junk_len:

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

Иногда uuid достаточно короткий, и если вам не нравятся тире, вы можете ays.replace («-», «») их

from uuid import uuid4 

random_string = str(uuid4()) 

Если вы хотите ему определенную длину без черточек

random_string_length = 16 
str(uuid4()).replace('-', '')[:random_string_length] 
+0

или использовать 'uuid4(). Hex', чтобы получить значение без дефис – davoclavo

Смежные вопросы