Cách nhẹ nhất để tạo một chuỗi ngẫu nhiên gồm 30 ký tự như sau là gì?
ufhy3skj5nca0d2dfh9hwd2tbk9sw1
Và một số thập lục phân gồm 30 chữ số như sau?
8c6f78ac23b4a7b8c0182d7a89e9b1
Câu trả lời:
Tôi có một cái nhanh hơn cho đầu ra hex. Sử dụng t1 và t2 tương tự như trên:
>>> t1 = timeit.Timer("''.join(random.choice('0123456789abcdef') for n in xrange(30))", "import random")
>>> t2 = timeit.Timer("binascii.b2a_hex(os.urandom(15))", "import os, binascii")
>>> t3 = timeit.Timer("'%030x' % random.randrange(16**30)", "import random")
>>> for t in t1, t2, t3:
... t.timeit()
...
28.165037870407104
9.0292739868164062
5.2836320400238037
t3 chỉ thực hiện một lệnh gọi đến mô-đun ngẫu nhiên, không phải tạo hoặc đọc danh sách, sau đó thực hiện phần còn lại với định dạng chuỗi.
string.hexdigits: stackoverflow.com/a/15462293/311288 " string.hexdigitstrả về 0123456789abcdefABCDEF(cả chữ thường và chữ hoa), [...]. Thay vào đó, chỉ cần sử dụng random.choice('0123456789abcdef')."
getrandbitsthay vì randrangeđể làm cho nó nhanh hơn.
'%030x' % random.getrandbits(60)thậm chí còn nhanh hơn so với '%030x' % random.randrange(16**30), có thể bởi vì nó không có không cần phải làm bất kỳ chuyển đổi sang / từ lớn ints
Chuỗi hex 30 chữ số:
>>> import os,binascii
>>> print binascii.b2a_hex(os.urandom(15))
"c84766ca4a3ce52c3602bbf02ad1f7"
Ưu điểm là điều này nhận được ngẫu nhiên trực tiếp từ Hệ điều hành, có thể an toàn hơn và / hoặc nhanh hơn ngẫu nhiên () và bạn không phải gieo nó.
Trong Py3.6 +, một tùy chọn khác là sử dụng secretsmô-đun tiêu chuẩn mới :
>>> import secrets
>>> secrets.token_hex(15)
'8d9bad5b43259c6ee27d9aadc7b832'
>>> secrets.token_urlsafe(22) # may include '_-' unclear if that is acceptable
'teRq7IqhaRU0S3euX1ji9f58WzUkrg'
import string
import random
lst = [random.choice(string.ascii_letters + string.digits) for n in xrange(30)]
str = "".join(lst)
print str
ocwbKCiuAJLRJgM1bWNV1TPSH0F2Lb
random.SystemRandom().choice
Giải pháp nhanh hơn đáng kể so với những giải pháp ở đây:
timeit("'%0x' % getrandbits(30 * 4)", "from random import getrandbits")
0.8056681156158447
%timeit '%030x' % randrange(16**30)cho 1000000 vòng, tốt nhất là 3: 1,61 ms mỗi vòng lặp while %timeit '%0x' % getrandbits(30 * 4)cho 1000000 vòng, tốt nhất là 3: 396 ns mỗi vòng lặp
Lưu ý: random.choice(string.hexdigits)không chính xác, vì string.hexdigitstrả về 0123456789abcdefABCDEF(cả chữ thường và chữ hoa), vì vậy bạn sẽ nhận được kết quả thiên vị, với chữ số thập lục phân 'c' có khả năng xuất hiện gấp đôi chữ số '7'. Thay vào đó, chỉ cần sử dụng random.choice('0123456789abcdef').
In [1]: import random
In [2]: hex(random.getrandbits(16))
Out[2]: '0x3b19'
Ngẫu nhiên, đây là kết quả của việc sử dụng timeithai cách tiếp cận đã được đề xuất:
Sử dụng random.choice():
>>> t1 = timeit.Timer("''.join(random.choice(string.hexdigits) for n in xrange(30))", "import random, string")
>>> t1.timeit()
69.558588027954102
Sử dụng binascii.b2a_hex():
>>> t2 = timeit.Timer("binascii.b2a_hex(os.urandom(15))", "import os, binascii")
>>> t2.timeit()
16.288421154022217
Có một cái nhanh hơn so với những gì jcdyer đã đề cập. Điều này chiếm ~ 50% phương pháp nhanh nhất của anh ấy.
from numpy.random.mtrand import RandomState
import binascii
rand = RandomState()
lo = 1000000000000000
hi = 999999999999999999
binascii.b2a_hex(rand.randint(lo, hi, 2).tostring())[:30]
>>> timeit.Timer("binascii.b2a_hex(rand.randint(lo,hi,2).tostring())[:30]", \
... 'from __main__ import lo,hi,rand,binascii').timeit()
1.648831844329834 <-- this is on python 2.6.6
2.253110885620117 <-- this on python 2.7.5
Nếu bạn muốn trong base64:
binascii.b2a_base64(rand.randint(lo, hi, 3).tostring())[:30]
Bạn có thể thay đổi tham số kích thước được truyền vào randint (last arg) để thay đổi độ dài đầu ra dựa trên yêu cầu của bạn. Vì vậy, đối với một ký tự 60:
binascii.b2a_hex(rand.randint(lo, hi, 4).tostring())[:60]
binascii.b2a_hex(np.random.rand(np.ceil(N/16)).view(dtype=int))[:N]ở đâu N=30.
thêm một câu trả lời nữa vào hỗn hợp hoạt động nhanh hơn giải pháp @eemz và cũng có đầy đủ chữ và số. Lưu ý rằng điều này không cung cấp cho bạn câu trả lời theo hệ thập phân.
import random
import string
LETTERS_AND_DIGITS = string.ascii_letters + string.digits
def random_choice_algo(width):
return ''.join(random.choice(LETTERS_AND_DIGITS) for i in range(width))
def random_choices_algo(width):
return ''.join(random.choices(LETTERS_AND_DIGITS, k=width))
print(generate_random_string(10))
# prints "48uTwINW1D"
điểm chuẩn nhanh chóng mang lại
from timeit import timeit
from functools import partial
arg_width = 10
print("random_choice_algo", timeit(partial(random_choice_algo, arg_width)))
# random_choice_algo 8.180561417000717
print("random_choices_algo", timeit(partial(random_choices_algo, arg_width)))
# random_choices_algo 3.172438014007639
Đây chắc chắn không phải là phiên bản nhẹ nhất, nhưng nó là ngẫu nhiên và rất dễ dàng để điều chỉnh bảng chữ cái / độ dài bạn muốn:
import random
def generate(random_chars=12, alphabet="0123456789abcdef"):
r = random.SystemRandom()
return ''.join([r.choice(alphabet) for i in range(random_chars)])