Случайные строки в Python 2.6 (это нормально?) - PullRequest
77 голосов
/ 24 апреля 2009

Я пытался найти более питонный способ генерирования случайной строки в питоне, который также может масштабироваться. Обычно я вижу что-то похожее на

''.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]

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

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

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

Ответы [ 5 ]

131 голосов
/ 24 апреля 2009
import os
random_string = os.urandom(string_length)

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

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

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

10 голосов
/ 31 августа 2012

Иногда uuid достаточно короткий, и если вам не нравятся тире, вы всегда можете их заменить.

from uuid import uuid4

random_string = str(uuid4())

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

random_string_length = 16
str(uuid4()).replace('-', '')[:random_string_length]
6 голосов
/ 24 апреля 2009

Взято из отчета об ошибке 1023290 на Python.org:

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

Также см. Выпуски 923643 и 1023290

2 голосов
/ 02 июня 2009

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

junk_len = 1024
junk =  (("%%0%dX" % (junk_len * 2)) % random.getrandbits(junk_len * 8)).decode("hex")
2 голосов
/ 24 апреля 2009

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

...