Случайные строки в 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")