Tôi muốn tạo một chuỗi có kích thước N.
Nó nên được tạo thành từ số và chữ in hoa như:
- 6U1S75
- 4Z4UKK
- U911K4
Làm thế nào tôi có thể đạt được điều này một cách pythonic ?
Tôi muốn tạo một chuỗi có kích thước N.
Nó nên được tạo thành từ số và chữ in hoa như:
Làm thế nào tôi có thể đạt được điều này một cách pythonic ?
Câu trả lời:
Trả lời trong một dòng:
''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))
hoặc thậm chí ngắn hơn bắt đầu với Python 3.6 bằng cách sử dụng random.choices()
:
''.join(random.choices(string.ascii_uppercase + string.digits, k=N))
Một phiên bản an toàn hơn về mật mã; xem https://stackoverflow.com/a/23728630/2213647 :
''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))
Trong chi tiết, với chức năng sạch để sử dụng lại:
>>> import string
>>> import random
>>> def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
... return ''.join(random.choice(chars) for _ in range(size))
...
>>> id_generator()
'G5G74W'
>>> id_generator(3, "6793YUIO")
'Y3U'
Làm thế nào nó hoạt động ?
Chúng tôi nhập string
, một mô-đun chứa các chuỗi ký tự ASCII phổ biến và random
mô-đun liên quan đến việc tạo ngẫu nhiên.
string.ascii_uppercase + string.digits
chỉ nối các danh sách các ký tự đại diện cho các ký tự và chữ số ASCII viết hoa:
>>> string.ascii_uppercase
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.digits
'0123456789'
>>> string.ascii_uppercase + string.digits
'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
Sau đó, chúng tôi sử dụng một sự hiểu biết danh sách để tạo một danh sách các yếu tố 'n':
>>> range(4) # range create a list of 'n' numbers
[0, 1, 2, 3]
>>> ['elem' for _ in range(4)] # we use range to create 4 times 'elem'
['elem', 'elem', 'elem', 'elem']
Trong ví dụ trên, chúng tôi sử dụng [
để tạo danh sách, nhưng chúng tôi không có id_generator
chức năng này nên Python không tạo danh sách trong bộ nhớ, nhưng tạo ra các phần tử một cách nhanh chóng (từng phần một ở đây ).
Thay vì yêu cầu tạo 'n' lần chuỗi elem
, chúng tôi sẽ yêu cầu Python tạo 'n' lần một ký tự ngẫu nhiên, được chọn từ một chuỗi các ký tự:
>>> random.choice("abcde")
'a'
>>> random.choice("abcde")
'd'
>>> random.choice("abcde")
'b'
Do đó random.choice(chars) for _ in range(size)
thực sự là tạo ra một chuỗi các size
nhân vật. Các ký tự được chọn ngẫu nhiên từ chars
:
>>> [random.choice('abcde') for _ in range(3)]
['a', 'b', 'b']
>>> [random.choice('abcde') for _ in range(3)]
['e', 'b', 'e']
>>> [random.choice('abcde') for _ in range(3)]
['d', 'a', 'c']
Sau đó, chúng ta chỉ cần nối chúng với một chuỗi rỗng để chuỗi trở thành một chuỗi:
>>> ''.join(['a', 'b', 'b'])
'abb'
>>> [random.choice('abcde') for _ in range(3)]
['d', 'c', 'b']
>>> ''.join(random.choice('abcde') for _ in range(3))
'dac'
range
bằng xrange
.
random
bằng random.SystemRandom()
: github.com/django/django/blob/ mẹo
random.sample
tạo các mẫu mà không cần thay thế, nói cách khác, không có khả năng lặp lại các ký tự, không nằm trong yêu cầu của OP. Tôi không nghĩ rằng đó là mong muốn cho hầu hết các ứng dụng.
Câu hỏi về Stack Overflow này là kết quả hàng đầu của Google hiện tại cho "chuỗi Python ngẫu nhiên". Câu trả lời hàng đầu hiện nay là:
''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))
Đây là một phương pháp tuyệt vời, nhưng PRNG một cách ngẫu nhiên không an toàn về mặt mật mã. Tôi giả sử nhiều người nghiên cứu câu hỏi này sẽ muốn tạo các chuỗi ngẫu nhiên để mã hóa hoặc mật khẩu. Bạn có thể thực hiện việc này một cách an toàn bằng cách thực hiện một thay đổi nhỏ trong đoạn mã trên:
''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))
Sử dụng random.SystemRandom()
thay vì chỉ sử dụng ngẫu nhiên / dev / urandom trên các máy * nix và CryptGenRandom()
trong Windows. Đây là những PRNG an toàn về mật mã. Sử dụng random.choice
thay vì random.SystemRandom().choice
trong một ứng dụng yêu cầu PRNG an toàn có thể có khả năng tàn phá nghiêm trọng và với sự phổ biến của câu hỏi này, tôi cá rằng sai lầm đó đã được thực hiện nhiều lần.
Nếu bạn đang sử dụng python3.6 trở lên, bạn có thể sử dụng mô-đun bí mật mới như được đề cập trong câu trả lời của MSeifert :
''.join(secrets.choice(string.ascii_uppercase + string.digits) for _ in range(N))
Các tài liệu mô-đun cũng thảo luận về các cách thuận tiện để tạo mã thông báo an toàn và thực tiễn tốt nhất .
random
đã cảnh báo điều này: " Cảnh báo : Không nên sử dụng trình tạo giả ngẫu nhiên của mô-đun này cho mục đích bảo mật. Sử dụng os.urandom () hoặc SystemRandom nếu bạn yêu cầu trình tạo số giả ngẫu nhiên an toàn bằng mật mã. " Đây là ref: Random.SystemRandom và os.urandom
string.uppercase
có thể dẫn đến kết quả không mong muốn tùy thuộc vào bộ ngôn ngữ. Sử dụng string.ascii_uppercase
(hoặc string.ascii_letters + string.digits
cho cơ sở62 thay vì cơ sở36) sẽ an toàn hơn trong trường hợp liên quan đến mã hóa.
xrange
thay vì range
cái sau tạo danh sách trong bộ nhớ, trong khi cái trước tạo ra một trình vòng lặp.
Nếu UUID ổn cho mục đích của bạn, hãy sử dụng gói uuid tích hợp.
import uuid; uuid.uuid4().hex.upper()[0:6]
Thí dụ:
import uuid
uuid.uuid4() #uuid4 => full random uuid
# Outputs something like: UUID('0172fc9a-1dac-4414-b88d-6b9a6feb91ea')
Nếu bạn cần chính xác định dạng của mình (ví dụ: "6U1S75"), bạn có thể làm như thế này:
import uuid
def my_random_string(string_length=10):
"""Returns a random string of length string_length."""
random = str(uuid.uuid4()) # Convert UUID format to a Python string.
random = random.upper() # Make all characters uppercase.
random = random.replace("-","") # Remove the UUID '-'.
return random[0:string_length] # Return the random string.
print(my_random_string(6)) # For example, D9E50C
string_length
, xác suất va chạm có thể là một mối quan tâm.
Một cách đơn giản hơn, nhanh hơn nhưng ít ngẫu nhiên hơn là sử dụng random.sample
thay vì chọn riêng từng chữ cái, Nếu cho phép lặp lại n, hãy phóng to cơ sở ngẫu nhiên của bạn thêm n lần, ví dụ:
import random
import string
char_set = string.ascii_uppercase + string.digits
print ''.join(random.sample(char_set*6, 6))
Lưu ý: Random.sample ngăn chặn việc sử dụng lại ký tự, nhân kích thước của bộ ký tự tạo ra nhiều lần lặp lại, nhưng chúng vẫn ít có khả năng sau đó chúng nằm trong một lựa chọn ngẫu nhiên thuần túy. Nếu chúng ta chọn một chuỗi có độ dài 6 và chúng ta chọn 'X' làm ký tự đầu tiên, trong ví dụ lựa chọn, tỷ lệ nhận được 'X' cho ký tự thứ hai cũng giống như tỷ lệ nhận 'X' là nhân vật đầu tiên. Trong triển khai Random.sample, tỷ lệ nhận được 'X' là bất kỳ ký tự tiếp theo nào chỉ có 6/7 cơ hội nhận được nó làm ký tự đầu tiên
sample
bạn sẽ không bao giờ có cùng một ký tự được liệt kê hai lần. Tất nhiên, nó sẽ thất bại N
cao hơn 36
.
import uuid
lowercase_str = uuid.uuid4().hex
lowercase_str
là một giá trị ngẫu nhiên như 'cea8b32e00934aaea8c005a35d85a5c0'
uppercase_str = lowercase_str.upper()
uppercase_str
Là 'CEA8B32E00934AAEA8C005A35D85A5C0'
uppercase_str[:N+1]
Một cách nhanh hơn, dễ dàng hơn và linh hoạt hơn để làm điều này là sử dụng strgen
mô-đun ( pip install StringGenerator
).
Tạo một chuỗi ngẫu nhiên gồm 6 ký tự với các chữ cái và chữ số viết hoa:
>>> from strgen import StringGenerator as SG
>>> SG("[\u\d]{6}").render()
u'YZI2CI'
Nhận một danh sách duy nhất:
>>> SG("[\l\d]{10}").render_list(5,unique=True)
[u'xqqtmi1pOk', u'zmkWdUr63O', u'PGaGcPHrX2', u'6RZiUbkk2i', u'j9eIeeWgEF']
Đảm bảo một ký tự "đặc biệt" trong chuỗi:
>>> SG("[\l\d]{10}&[\p]").render()
u'jaYI0bcPG*0'
Một màu HTML ngẫu nhiên:
>>> SG("#[\h]{6}").render()
u'#CEdFCa'
Vân vân.
Chúng ta cần lưu ý rằng:
''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))
có thể không có chữ số (hoặc ký tự viết hoa) trong đó.
strgen
nhanh hơn trong thời gian dành cho nhà phát triển so với bất kỳ giải pháp nào ở trên. Giải pháp từ Ignacio là hiệu suất thời gian chạy nhanh nhất và là câu trả lời đúng khi sử dụng Thư viện chuẩn Python. Nhưng bạn sẽ hầu như không bao giờ sử dụng nó trong hình thức đó. Bạn sẽ muốn sử dụng SystemRandom (hoặc dự phòng nếu không có), đảm bảo các bộ ký tự được yêu cầu được trình bày, sử dụng unicode (hoặc không), đảm bảo các lệnh liên tiếp tạo ra một chuỗi duy nhất, sử dụng tập hợp con của một trong các lớp ký tự mô-đun chuỗi, vv Tất cả điều này đòi hỏi nhiều mã hơn trong các câu trả lời được cung cấp. Tất cả các nỗ lực khác nhau để khái quát hóa một giải pháp đều có những hạn chế mà strgen giải quyết với sức mạnh và sức mạnh biểu cảm lớn hơn bằng cách sử dụng một ngôn ngữ mẫu đơn giản.
Đó là trên PyPI:
pip install StringGenerator
Tiết lộ: Tôi là tác giả của mô-đun strgen.
Từ Python 3.6, bạn nên sử dụng secrets
mô-đun nếu bạn cần bảo mật bằng mật mã thay vì random
mô-đun (nếu không câu trả lời này giống hệt với mô-đun @Ignacio Vazquez-Abrams):
from secrets import choice
import string
''.join([choice(string.ascii_uppercase + string.digits) for _ in range(N)])
Một lưu ý bổ sung: trong trường hợp hiểu danh sách sẽ nhanh hơn trong việc str.join
sử dụng biểu thức trình tạo!
Dựa trên một câu trả lời Stack Overflow khác, Cách nhẹ nhất để tạo một chuỗi ngẫu nhiên và một số thập lục phân ngẫu nhiên , một phiên bản tốt hơn câu trả lời được chấp nhận sẽ là:
('%06x' % random.randrange(16**6)).upper()
nhanh hơn nhiều.
N
.
Nếu bạn cần một chuỗi ngẫu nhiên thay vì một chuỗi ngẫu nhiên giả , bạn nên sử dụng os.urandom
làm nguồn
from os import urandom
from itertools import islice, imap, repeat
import string
def rand_string(length=5):
chars = set(string.ascii_uppercase + string.digits)
char_gen = (c for c in imap(urandom, repeat(1)) if c in chars)
return ''.join(islice(char_gen, None, length))
os.urandom
không giả ngẫu nhiên? Nó có thể đang sử dụng một thuật toán tốt hơn để tạo ra các số ngẫu nhiên hơn, nhưng nó vẫn là giả ngẫu nhiên.
/dev/random
và /dev/urandom
. Vấn đề là /dev/random
các khối khi không có đủ entropy làm hạn chế tính hữu dụng của nó. Đối với một miếng đệm một lần /dev/urandom
là không đủ tốt, nhưng tôi nghĩ nó tốt hơn giả ngẫu nhiên ở đây.
/dev/random
và /dev/urandom
là giả ngẫu nhiên, nhưng nó có thể phụ thuộc vào định nghĩa của bạn.
Tôi nghĩ rằng không ai đã trả lời này lol! Nhưng này, đây là của riêng tôi đi vào nó:
import random
def random_alphanumeric(limit):
#ascii alphabet of all alphanumerals
r = (range(48, 58) + range(65, 91) + range(97, 123))
random.shuffle(r)
return reduce(lambda i, s: i + chr(s), r[:random.randint(0, len(r))], "")
Phương thức này nhanh hơn một chút và khó chịu hơn một chút so với phương thức Random.choice () mà Ignacio đã đăng.
Nó lợi dụng bản chất của các thuật toán giả ngẫu nhiên, và các ngân hàng trên bitwise và thay đổi nhanh hơn so với việc tạo ra một số ngẫu nhiên mới cho mỗi ký tự.
# must be length 32 -- 5 bits -- the question didn't specify using the full set
# of uppercase letters ;)
_ALPHABET = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'
def generate_with_randbits(size=32):
def chop(x):
while x:
yield x & 31
x = x >> 5
return ''.join(_ALPHABET[x] for x in chop(random.getrandbits(size * 5))).ljust(size, 'A')
... tạo một trình tạo lấy ra 5 số bit tại một thời điểm 0..31 cho đến khi không còn lại
... tham gia () kết quả của trình tạo trên một số ngẫu nhiên với các bit đúng
Với Timeit, đối với chuỗi 32 ký tự, thời gian là:
[('generate_with_random_choice', 28.92901611328125),
('generate_with_randbits', 20.0293550491333)]
... nhưng đối với chuỗi 64 ký tự, randbits bị mất;)
Tôi có lẽ sẽ không bao giờ sử dụng phương pháp này trong mã sản xuất trừ khi tôi thực sự không thích đồng nghiệp của mình.
chỉnh sửa: được cập nhật cho phù hợp với câu hỏi (chỉ chữ hoa và chữ số) và sử dụng toán tử bitwise & và >> thay vì% và //
Tôi sẽ làm theo cách này:
import random
from string import digits, ascii_uppercase
legals = digits + ascii_uppercase
def rand_string(length, char_set=legals):
output = ''
for _ in range(length): output += random.choice(char_set)
return output
Hoặc chỉ:
def rand_string(length, char_set=legals):
return ''.join( random.choice(char_set) for _ in range(length) )
Sử dụng hàm Random.choice () của Numpy
import numpy as np
import string
if __name__ == '__main__':
length = 16
a = np.random.choice(list(string.ascii_uppercase + string.digits), length)
print(''.join(a))
Tài liệu ở đây http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.random.choice.html
>>> import string
>>> import random
logic sau vẫn tạo mẫu ngẫu nhiên 6 ký tự
>>> print ''.join(random.sample((string.ascii_uppercase+string.digits),6))
JT7K3Q
Không cần nhân với 6
>>> print ''.join(random.sample((string.ascii_uppercase+string.digits)*6,6))
TK82HK
Đối với những người bạn thích python chức năng:
from itertools import imap, starmap, islice, repeat
from functools import partial
from string import letters, digits, join
from random import choice
join_chars = partial(join, sep='')
identity = lambda o: o
def irand_seqs(symbols=join_chars((letters, digits)), length=6, join=join_chars, select=choice, breakup=islice):
""" Generates an indefinite sequence of joined random symbols each of a specific length
:param symbols: symbols to select,
[defaults to string.letters + string.digits, digits 0 - 9, lower and upper case English letters.]
:param length: the length of each sequence,
[defaults to 6]
:param join: method used to join selected symbol,
[defaults to ''.join generating a string.]
:param select: method used to select a random element from the giving population.
[defaults to random.choice, which selects a single element randomly]
:return: indefinite iterator generating random sequences of giving [:param length]
>>> from tools import irand_seqs
>>> strings = irand_seqs()
>>> a = next(strings)
>>> assert isinstance(a, (str, unicode))
>>> assert len(a) == 6
>>> assert next(strings) != next(strings)
"""
return imap(join, starmap(breakup, repeat((imap(select, repeat(symbols)), None, length))))
Nó tạo ra một trình lặp [vô hạn] không xác định, các chuỗi ngẫu nhiên được nối, bằng cách đầu tiên tạo ra một chuỗi ký hiệu được chọn ngẫu nhiên không xác định từ nhóm đưa ra, sau đó chia chuỗi này thành các phần có độ dài được nối, nó sẽ hoạt động với bất kỳ chuỗi nào hỗ trợ getitem , theo mặc định, nó chỉ đơn giản tạo ra một chuỗi các chữ số alpha ngẫu nhiên, mặc dù bạn có thể dễ dàng sửa đổi để tạo ra những thứ khác:
ví dụ để tạo các bộ chữ số ngẫu nhiên:
>>> irand_tuples = irand_seqs(xrange(10), join=tuple)
>>> next(irand_tuples)
(0, 5, 5, 7, 2, 8)
>>> next(irand_tuples)
(3, 2, 2, 0, 3, 1)
nếu bạn không muốn sử dụng tiếp theo cho thế hệ, bạn chỉ cần làm cho nó có thể gọi được:
>>> irand_tuples = irand_seqs(xrange(10), join=tuple)
>>> make_rand_tuples = partial(next, irand_tuples)
>>> make_rand_tuples()
(1, 6, 2, 8, 1, 9)
nếu bạn muốn tạo chuỗi nhanh, chỉ cần đặt tham gia vào danh tính.
>>> irand_tuples = irand_seqs(xrange(10), join=identity)
>>> selections = next(irand_tuples)
>>> next(selections)
8
>>> list(selections)
[6, 3, 8, 2, 2]
Như những người khác đã đề cập nếu bạn cần bảo mật hơn thì hãy thiết lập chức năng chọn phù hợp:
>>> from random import SystemRandom
>>> rand_strs = irand_seqs(select=SystemRandom().choice)
'QsaDxQ'
bộ chọn mặc định choice
có thể chọn cùng một biểu tượng nhiều lần cho mỗi khối, nếu thay vào đó, bạn muốn cùng một thành viên được chọn nhiều nhất cho mỗi khối sau đó, một cách sử dụng có thể:
>>> from random import sample
>>> irand_samples = irand_seqs(xrange(10), length=1, join=next, select=lambda pool: sample(pool, 6))
>>> next(irand_samples)
[0, 9, 2, 3, 1, 6]
chúng tôi sử dụng sample
làm công cụ chọn của mình, để thực hiện lựa chọn hoàn chỉnh, vì vậy các khối thực sự có độ dài 1 và để tham gia, chúng tôi chỉ đơn giản gọi phần next
nào tìm nạp đoạn được tạo hoàn toàn tiếp theo, với ví dụ này có vẻ hơi cồng kềnh và nó ...
(1) Điều này sẽ cung cấp cho bạn tất cả các chữ hoa và số:
import string, random
passkey=''
for x in range(8):
if random.choice([1,2]) == 1:
passkey += passkey.join(random.choice(string.ascii_uppercase))
else:
passkey += passkey.join(random.choice(string.digits))
print passkey
(2) Nếu sau này bạn muốn bao gồm các chữ cái viết thường trong khóa của mình, thì điều này cũng sẽ hoạt động:
import string, random
passkey=''
for x in range(8):
if random.choice([1,2]) == 1:
passkey += passkey.join(random.choice(string.ascii_letters))
else:
passkey += passkey.join(random.choice(string.digits))
print passkey
đây là một phản ứng của Anurag Uniyal và một cái gì đó mà tôi đang tự làm việc.
import random
import string
oneFile = open('Numbers.txt', 'w')
userInput = 0
key_count = 0
value_count = 0
chars = string.ascii_uppercase + string.digits + string.punctuation
for userInput in range(int(input('How many 12 digit keys do you want?'))):
while key_count <= userInput:
key_count += 1
number = random.randint(1, 999)
key = number
text = str(key) + ": " + str(''.join(random.sample(chars*6, 12)))
oneFile.write(text + "\n")
oneFile.close()
>>> import random
>>> str = []
>>> chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
>>> num = int(raw_input('How long do you want the string to be? '))
How long do you want the string to be? 10
>>> for k in range(1, num+1):
... str.append(random.choice(chars))
...
>>> str = "".join(str)
>>> str
'tm2JUQ04CK'
Các random.choice
chức năng chọn một mục ngẫu nhiên trong danh sách. Bạn cũng tạo một danh sách để bạn có thể nối thêm ký tự trong for
câu lệnh. Ở cuối str là ['t', 'm', '2', 'J', 'U', 'Q', '0', '4', 'C', 'K'], nhưng str = "".join(str)
mất quan tâm đến điều đó, để lại cho bạn với 'tm2JUQ04CK'
.
Hi vọng điêu nay co ich!
range(num)
thay thế, và str có thể là một chuỗi str += random.choice(chars)
.
import string
from random import *
characters = string.ascii_letters + string.punctuation + string.digits
password = "".join(choice(characters) for x in range(randint(8, 16)))
print password
import random
q=2
o=1
list =[r'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','s','0','1','2','3','4','5','6','7','8','9','0']
while(q>o):
print("")
for i in range(1,128):
x=random.choice(list)
print(x,end="")
Ở đây độ dài của chuỗi có thể được thay đổi trong vòng lặp for, tức là cho i trong phạm vi (1, độ dài) Đây là thuật toán đơn giản, dễ hiểu. nó sử dụng danh sách để bạn có thể loại bỏ các ký tự mà bạn không cần.
Một cái đơn giãn:
import string
import random
character = string.lowercase + string.uppercase + string.digits + string.punctuation
char_len = len(character)
# you can specify your password length here
pass_len = random.randint(10,20)
password = ''
for x in range(pass_len):
password = password + character[random.randint(0,char_len-1)]
print password
Hai phương pháp:
import random, math
def randStr_1(chars:str, length:int) -> str:
chars *= math.ceil(length / len(chars))
chars = letters[0:length]
chars = list(chars)
random.shuffle(characters)
return ''.join(chars)
def randStr_2(chars:str, length:int) -> str:
return ''.join(random.choice(chars) for i in range(chars))
Điểm chuẩn:
from timeit import timeit
setup = """
import os, subprocess, time, string, random, math
def randStr_1(letters:str, length:int) -> str:
letters *= math.ceil(length / len(letters))
letters = letters[0:length]
letters = list(letters)
random.shuffle(letters)
return ''.join(letters)
def randStr_2(letters:str, length:int) -> str:
return ''.join(random.choice(letters) for i in range(length))
"""
print('Method 1 vs Method 2', ', run 10 times each.')
for length in [100,1000,10000,50000,100000,500000,1000000]:
print(length, 'characters:')
eff1 = timeit("randStr_1(string.ascii_letters, {})".format(length), setup=setup, number=10)
eff2 = timeit("randStr_2(string.ascii_letters, {})".format(length), setup=setup, number=10)
print('\t{}s : {}s'.format(round(eff1, 6), round(eff2, 6)))
print('\tratio = {} : {}\n'.format(eff1/eff1, round(eff2/eff1, 2)))
Đầu ra:
Method 1 vs Method 2 , run 10 times each.
100 characters:
0.001411s : 0.00179s
ratio = 1.0 : 1.27
1000 characters:
0.013857s : 0.017603s
ratio = 1.0 : 1.27
10000 characters:
0.13426s : 0.151169s
ratio = 1.0 : 1.13
50000 characters:
0.709403s : 0.855136s
ratio = 1.0 : 1.21
100000 characters:
1.360735s : 1.674584s
ratio = 1.0 : 1.23
500000 characters:
6.754923s : 7.160508s
ratio = 1.0 : 1.06
1000000 characters:
11.232965s : 14.223914s
ratio = 1.0 : 1.27
Hiệu suất của phương pháp đầu tiên là tốt hơn.
Tôi đã đi qua gần như tất cả các câu trả lời nhưng không ai trong số chúng có vẻ dễ dàng hơn. Tôi sẽ đề nghị bạn thử thư viện passgen thường được sử dụng để tạo mật khẩu ngẫu nhiên.
Bạn có thể tạo các chuỗi ngẫu nhiên theo lựa chọn về độ dài, dấu câu, chữ số, chữ cái và chữ hoa .
Đây là mã cho trường hợp của bạn:
from passgen import passgen
string_length = int(input())
random_string = passgen(length=string_length, punctuation=False, digits=True, letters=True, case='upper')
Tạo ID 16 byte ngẫu nhiên chứa các chữ cái, chữ số, '_' và '-'
os.urandom(16).translate((f'{string.ascii_letters}{string.digits}-_'*4).encode('ascii'))
Tôi đã xem xét các câu trả lời khác nhau và dành thời gian để đọc tài liệu về bí mật
Mô-đun bí mật được sử dụng để tạo các số ngẫu nhiên mạnh về mật mã phù hợp để quản lý dữ liệu như mật khẩu, xác thực tài khoản, mã thông báo bảo mật và các bí mật liên quan.
Đặc biệt, các bí mật nên được sử dụng để ưu tiên cho trình tạo số giả ngẫu nhiên mặc định trong mô-đun ngẫu nhiên, được thiết kế để mô hình hóa và mô phỏng, không phải bảo mật hoặc mật mã.
Tìm hiểu thêm về những gì nó cung cấp Tôi đã tìm thấy một chức năng rất tiện dụng nếu bạn muốn bắt chước một ID như ID Google Drive:
secret.token_urlsafe ([nbytes = Không])
Trả về một chuỗi văn bản an toàn URL ngẫu nhiên, chứa các byte ngẫu nhiên nbyte. Văn bản được mã hóa Base64, vì vậy trung bình mỗi byte cho kết quả xấp xỉ 1,3 ký tự . Nếu nbyte là Không hoặc không được cung cấp, một mặc định hợp lý được sử dụng.
Sử dụng theo cách sau:
import secrets
import math
def id_generator():
id = secrets.token_urlsafe(math.floor(32 / 1.3))
return id
print(id_generator())
Xuất id có độ dài 32 ký tự:
joXR8dYbBDAHpVs5ci6iD-oIgPhkeQFk
Tôi biết điều này hơi khác so với câu hỏi của OP nhưng tôi hy vọng rằng nó vẫn hữu ích cho nhiều người đang tìm kiếm trường hợp sử dụng tương tự mà tôi đang tìm kiếm.
import string, random
lower = string.ascii_lowercase
upper = string.ascii_uppercase
digits = string.digits
special = '!"£$%^&*.,@#/?'
def rand_pass(l=4, u=4, d=4, s=4):
p = []
[p.append(random.choice(lower)) for x in range(l)]
[p.append(random.choice(upper)) for x in range(u)]
[p.append(random.choice(digits)) for x in range(d)]
[p.append(random.choice(special)) for x in range(s)]
random.shuffle(p)
return "".join(p)
print(rand_pass())
# @5U,@A4yIZvnp%51
Tôi thấy điều này là đơn giản và sạch sẽ hơn.
str_Key = ""
str_FullKey = ""
str_CharacterPool = "01234ABCDEFfghij~>()"
for int_I in range(64):
str_Key = random.choice(str_CharacterPool)
str_FullKey = str_FullKey + str_Key
Chỉ cần thay đổi 64 để thay đổi độ dài, thay đổi Ký tự để thực hiện chỉ alpha số hoặc chỉ số hoặc ký tự lạ hoặc bất cứ điều gì bạn muốn.