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


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

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

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

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

Он генерирует случайную строку 50mil на моем ноутбуке всего за 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]

edit

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

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

5 76

5 ответов:

import os
random_string = os.urandom(string_length)

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

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

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

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

from uuid import uuid4

random_string = str(uuid4())

Если вы хотите, чтобы он определенной длины без черточек

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

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

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

кроме того, смотрите вопросы 923643 и 1023290

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

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

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