Как говорит Дэн Д., давая numpy
генерировать ваши байты одним ударом со скоростью C, это будет способ быстрее, чем производить их по одному на скорости Python.
Однако, если вы не хотите использовать numpy
, вы можете сделать свой код немного более эффективным.
Построение строки путем конкатенации, например, buf = buf + chr(random.randint(0,255))
происходит очень медленно, так как новый buf
должен быть выделен на каждом цикле (помните, что строки Python неизменяемы). Обычная техника в Python для построения строки из подстрок состоит в том, чтобы скопировать подстроки в списке, а затем использовать метод str.join()
, чтобы объединить их за один раз.
Мы также можем сэкономить немного времени, предварительно создавая список наших 1-байтовых строк, вместо того, чтобы звонить chr()
за каждый байт, который мы хотим.
from random import seed, choice
allbytes = [chr(i) for i in range(256)]
def random_bytes(n):
bytes = []
for _ in range(n):
bytes.append(choice(allbytes))
return ''.join(bytes)
Мы можем упростить это и сделать его слегка более эффективным, используя список понимание:
def random_bytes(n):
return ''.join([choice(allbytes) for _ in range(n)])
В зависимости от того, как вы собираетесь использовать эти случайные байты, вы можете найти его полезно поместить их в объект bytearray или bytes
.
Вот вариант на основе нового ответа cristianmtr в:
def random_bytes(n):
return bytes(bytearray(getrandbits(8) for _ in xrange(n)))
Вы могли использовать str()
вместо bytes()
, но bytes()
лучше для Python 3, поскольку Python 3 строки Unicode.
FWIW, 'urandom' получает свою случайность от случайного системного шума (см. [Справочная страница Linux для urandom] (http://linux.die.net/man/4/urandom)), поэтому он не делает чтобы дать возможность посева. Отсутствие посева является раздражающим для тестирования вещей, но OTOH делает его полезным источником случайности для криптографических целей. Я думаю, это не имеет особого отношения к вашему вопросу, но, по крайней мере, это объясняет, почему нет возможности его посеять. :) –