Случайные строки в Python 2.6 (это нормально?)

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

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

import os
random_string = os.urandom(string_length)

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

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

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

Ответ 2

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

from uuid import uuid4

random_string = str(uuid4())

Если вам нужна определенная длина без тире

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

Ответ 3

Из отчета 1023290 на Python.org:

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

Также см. проблемы 923643 и 1023290

Ответ 4

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

Ответ 5

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

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