ฉันต้องการสร้างสตริงที่มีขนาด N
ควรประกอบด้วยตัวเลขและตัวอักษรภาษาอังกฤษตัวพิมพ์ใหญ่เช่น:
- 6U1S75
- 4Z4UKK
- U911K4
ฉันจะทำสิ่งนี้สำเร็จในแบบpythonicอย่างไร
ฉันต้องการสร้างสตริงที่มีขนาด N
ควรประกอบด้วยตัวเลขและตัวอักษรภาษาอังกฤษตัวพิมพ์ใหญ่เช่น:
ฉันจะทำสิ่งนี้สำเร็จในแบบpythonicอย่างไร
คำตอบ:
ตอบในหนึ่งบรรทัด:
''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))
หรือแม้แต่เริ่มสั้นลงด้วย Python 3.6 โดยใช้random.choices()
:
''.join(random.choices(string.ascii_uppercase + string.digits, k=N))
รุ่นที่ปลอดภัยยิ่งขึ้นการเข้ารหัส ดูhttps://stackoverflow.com/a/23728630/2213647 :
''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))
ในรายละเอียดด้วยฟังก์ชั่นใหม่ทั้งหมด:
>>> 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'
มันทำงานยังไง?
เรานำเข้าstring
โมดูลที่มีลำดับของอักขระ ASCII ทั่วไปและrandom
โมดูลที่เกี่ยวข้องกับการสร้างแบบสุ่ม
string.ascii_uppercase + string.digits
เพียงเชื่อมรายชื่ออักขระที่เป็นตัวอักษรตัวพิมพ์ใหญ่ ASCII และตัวเลข:
>>> string.ascii_uppercase
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.digits
'0123456789'
>>> string.ascii_uppercase + string.digits
'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
จากนั้นเราจะใช้ list comprehension เพื่อสร้างรายการขององค์ประกอบ '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']
ในตัวอย่างข้างต้นเราใช้[
ในการสร้างรายการ แต่เราไม่ได้ทำid_generator
หน้าที่ดังนั้น Python ไม่สร้างรายการในหน่วยความจำ แต่สร้างองค์ประกอบได้ทันทีโดยหนึ่งต่อหนึ่ง (เพิ่มเติมเกี่ยวกับที่นี่ )
แทนที่จะขอให้สร้าง 'n' คูณสตริงelem
เราจะขอให้ Python สร้าง 'n' คูณด้วยอักขระสุ่มเลือกจากลำดับของอักขระ:
>>> random.choice("abcde")
'a'
>>> random.choice("abcde")
'd'
>>> random.choice("abcde")
'b'
ดังนั้นrandom.choice(chars) for _ in range(size)
จริงๆแล้วการสร้างลำดับของsize
ตัวละคร ตัวละครที่สุ่มมาจาก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']
จากนั้นเราก็รวมมันกับสตริงว่างเพื่อให้ลำดับกลายเป็นสตริง:
>>> ''.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
xrange
random
ด้วยrandom.SystemRandom()
: github.com/django/django/blob/…
random.sample
สร้างตัวอย่างโดยไม่มีการแทนที่กล่าวอีกนัยหนึ่งโดยไม่มีความเป็นไปได้ที่จะทำซ้ำอักขระซึ่งไม่ได้อยู่ในข้อกำหนดของ OP ฉันไม่คิดว่ามันจะเป็นที่พึงปรารถนาสำหรับการใช้งานส่วนใหญ่
Quesion Stack Overflow นี้เป็นผลการค้นหาอันดับต้น ๆ ของ Google ในปัจจุบันสำหรับ "Random string Python" คำตอบยอดนิยมปัจจุบันคือ:
''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))
นี่เป็นวิธีการที่ยอดเยี่ยม แต่PRNGแบบสุ่มไม่มีความปลอดภัยในการเข้ารหัส ฉันคิดว่าหลายคนค้นคว้าคำถามนี้จะต้องการสร้างสตริงสุ่มสำหรับการเข้ารหัสหรือรหัสผ่าน คุณสามารถทำได้อย่างปลอดภัยโดยทำการเปลี่ยนแปลงเล็กน้อยในโค้ดด้านบน:
''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))
การใช้random.SystemRandom()
แทนที่จะใช้แบบสุ่มใช้ / dev / urandom บนเครื่อง * nix และCryptGenRandom()
ใน Windows เหล่านี้มีความปลอดภัย PRNGs cryptographically การใช้random.choice
แทนrandom.SystemRandom().choice
แอปพลิเคชันที่ต้องใช้ PRNG ที่ปลอดภัยอาจทำลายล้างและได้รับความนิยมจากคำถามนี้ฉันพนันได้เลยว่าความผิดพลาดนั้นเกิดขึ้นหลายครั้งแล้ว
หากคุณใช้ python3.6 ขึ้นไปคุณสามารถใช้โมดูลลับใหม่ตามที่ระบุไว้ในคำตอบของ MSeifert :
''.join(secrets.choice(string.ascii_uppercase + string.digits) for _ in range(N))
โมดูลเอกสารยังหารือถึงวิธีที่สะดวกในการสร้างโทเค็นที่ปลอดภัยและแนวทางปฏิบัติที่ดีที่สุดปฏิบัติที่ดีที่สุด
random
ได้เตือนสิ่งนี้: " คำเตือน : เครื่องกำเนิดไฟฟ้าแบบหลอกเทียมของโมดูลนี้ไม่ควรใช้เพื่อจุดประสงค์ด้านความปลอดภัยใช้ os.urandom () หรือ SystemRandom หากคุณต้องการเครื่องกำเนิดเลขสุ่มแบบเข้ารหัสลับที่ปลอดภัย " นี่คือการอ้างอิง: random.SystemRandomและos.urandom
string.uppercase
สิ่งที่สามารถนำไปสู่ผลลัพธ์ที่ไม่คาดคิดขึ้นอยู่กับชุดภาษา การใช้string.ascii_uppercase
(หรือstring.ascii_letters + string.digits
สำหรับ base62 แทน base36) ปลอดภัยกว่าในกรณีที่เกี่ยวข้องกับการเข้ารหัส
xrange
แทนที่จะrange
เป็นรายการหลังสร้างรายการในหน่วยความจำในขณะที่อดีตสร้างตัววนซ้ำ
หาก UUID ไม่เป็นไรสำหรับวัตถุประสงค์ของคุณให้ใช้uuidในตัวแพ็คเกจตัว
import uuid; uuid.uuid4().hex.upper()[0:6]
ตัวอย่าง:
import uuid
uuid.uuid4() #uuid4 => full random uuid
# Outputs something like: UUID('0172fc9a-1dac-4414-b88d-6b9a6feb91ea')
หากคุณต้องการรูปแบบที่แน่นอน (เช่น "6U1S75") คุณสามารถทำได้ดังนี้:
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
ความน่าจะเป็นที่จะเกิดการชนนั้นขึ้นอยู่กับว่ามีขนาดเล็กเพียงใด
วิธีที่ง่ายกว่าเร็วกว่า แต่สุ่มน้อยกว่าคือใช้random.sample
แทนการเลือกตัวอักษรแต่ละตัวแยกกันถ้าอนุญาตให้ใช้การซ้ำซ้อนได้ให้ขยายพื้นฐานการสุ่มของคุณโดย n คูณเช่น
import random
import string
char_set = string.ascii_uppercase + string.digits
print ''.join(random.sample(char_set*6, 6))
หมายเหตุ: random.sample ป้องกันการใช้อักขระซ้ำการคูณขนาดของชุดอักขระทำให้สามารถทำซ้ำได้หลายครั้ง แต่ยังมีโอกาสน้อยกว่านั้นพวกเขาจะอยู่ในตัวเลือกแบบสุ่มล้วนๆ ถ้าเราไปหาสตริงที่มีความยาว 6 และเราเลือก 'X' เป็นตัวอักษรตัวแรกในตัวอย่างที่เลือกโอกาสที่จะได้ 'X' สำหรับตัวละครตัวที่สองนั้นเหมือนกับอัตราต่อรองที่จะได้รับ 'X' เป็น อักขระตัวแรก ในการนำมาใช้แบบสุ่มตัวอย่างอัตราต่อรองของการได้รับ 'X' เป็นอักขระตัวต่อมาใด ๆ ที่มีโอกาสเพียง 6/7 เท่านั้นในการได้รับมันเป็นตัวอักษรตัวแรก
sample
คุณจะไม่ได้รับตัวละครเดียวกันสองครั้ง นอกจากนี้ยังมีของหลักสูตรก็จะล้มเหลวสูงกว่าN
36
import uuid
lowercase_str = uuid.uuid4().hex
lowercase_str
เป็นค่าสุ่มเช่น 'cea8b32e00934aaea8c005a35d85a5c0'
uppercase_str = lowercase_str.upper()
uppercase_str
คือ 'CEA8B32E00934AAEA8C005A35D85A5C0'
uppercase_str[:N+1]
วิธีที่เร็วขึ้นง่ายขึ้นและยืดหยุ่นมากขึ้นในการทำเช่นนี้คือการใช้strgen
โมดูล ( pip install StringGenerator
)
สร้างสตริงสุ่ม 6 ตัวอักษรด้วยตัวอักษรตัวพิมพ์ใหญ่และตัวเลข:
>>> from strgen import StringGenerator as SG
>>> SG("[\u\d]{6}").render()
u'YZI2CI'
รับรายการที่ไม่ซ้ำกัน:
>>> SG("[\l\d]{10}").render_list(5,unique=True)
[u'xqqtmi1pOk', u'zmkWdUr63O', u'PGaGcPHrX2', u'6RZiUbkk2i', u'j9eIeeWgEF']
รับประกันอักขระ "พิเศษ" หนึ่งตัวในสตริง:
>>> SG("[\l\d]{10}&[\p]").render()
u'jaYI0bcPG*0'
สี HTML แบบสุ่ม:
>>> SG("#[\h]{6}").render()
u'#CEdFCa'
เป็นต้น
เราจำเป็นต้องตระหนักว่าสิ่งนี้:
''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))
อาจไม่มีตัวเลข (หรืออักขระตัวพิมพ์ใหญ่) ในนั้น
strgen
เร็วกว่าในช่วงเวลาของนักพัฒนาซอฟต์แวร์มากกว่าโซลูชันด้านบน การแก้ปัญหาจาก Ignacio เป็นวิธีการทำงานที่รวดเร็วที่สุดและเป็นคำตอบที่ถูกต้องโดยใช้ Python Standard Library แต่คุณแทบจะไม่เคยใช้มันในรูปแบบนั้น คุณจะต้องการใช้ SystemRandom (หรือสำรองหากไม่พร้อมใช้งาน) ตรวจสอบให้แน่ใจว่ามีการแสดงชุดอักขระที่จำเป็นใช้ unicode (หรือไม่) ตรวจสอบให้แน่ใจว่าการเรียกใช้แบบต่อเนื่องสร้างสตริงที่ไม่ซ้ำกันใช้ชุดย่อยของ ฯลฯ ทั้งหมดนี้ต้องใช้รหัสมากกว่าจำนวนมากในคำตอบที่ให้ไว้ ความพยายามที่หลากหลายในการวางแนวทางการแก้ปัญหาทั้งหมดมีข้อ จำกัด ที่ strgen แก้ไขด้วยความกะทัดรัดและพลังที่แสดงออกโดยใช้ภาษาเทมเพลตอย่างง่าย
มันอยู่ใน PyPI:
pip install StringGenerator
การเปิดเผยข้อมูล: ฉันเป็นผู้เขียนโมดูล strgen
จาก Python 3.6 คุณควรใช้secrets
โมดูลหากคุณต้องการให้มันปลอดภัยด้วยการเข้ารหัสแทนrandom
โมดูล (มิฉะนั้นคำตอบนี้จะเหมือนกับ @Ignacio Vazquez-Abrams):
from secrets import choice
import string
''.join([choice(string.ascii_uppercase + string.digits) for _ in range(N)])
หมายเหตุเพิ่มเติมอีกประการหนึ่ง: ความเข้าใจในรายการนั้นเร็วกว่าในกรณีที่str.join
ใช้นิพจน์ตัวสร้าง
ขึ้นอยู่กับคำตอบสแต็คโอเวอร์โฟลอื่นวิธีที่มีน้ำหนักเบาที่สุดในการสร้างสตริงแบบสุ่มและตัวเลขฐานสิบหกแบบสุ่มเวอร์ชันที่ดีกว่าคำตอบที่ยอมรับจะเป็น:
('%06x' % random.randrange(16**6)).upper()
เร็วกว่ามาก
N
parametrize
หากคุณต้องการสตริงสุ่มแทนที่จะเป็นแบบสุ่มหลอกคุณควรใช้os.urandom
เป็นแหล่งที่มา
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
ไม่ได้หลอกสุ่ม? อาจใช้อัลกอริธึมที่ดีกว่าในการสร้างตัวเลขที่สุ่มมากกว่า แต่ก็ยังสุ่มหลอก
/dev/random
/dev/urandom
ปัญหาคือ/dev/random
บล็อกเมื่อมีเอนโทรปีไม่เพียงพอซึ่ง จำกัด ประโยชน์ สำหรับแผ่นเวลาหนึ่ง /dev/urandom
ยังไม่ดีพอ แต่ฉันคิดว่ามันดีกว่าการสุ่มหลอกที่นี่
/dev/random
และ/dev/urandom
หลอกแบบสุ่ม แต่มันอาจขึ้นอยู่กับคำจำกัดความของคุณ
ฉันคิดว่าไม่มีใครตอบเรื่องนี้เลยฮ่า ๆ ! แต่เดี๋ยวก่อนนี่เป็นของฉันไปที่:
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))], "")
วิธีนี้เร็วกว่าเล็กน้อยและน่ารำคาญกว่าวิธี random.choice () วิธี Ignacio ที่โพสต์
มันใช้ประโยชน์จากธรรมชาติของอัลกอริธึมแบบหลอกเทียมและแบ๊งส์ในระดับบิตและเปลี่ยนเร็วกว่าการสร้างหมายเลขสุ่มใหม่สำหรับแต่ละตัวละคร
# 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')
... สร้างตัวสร้างที่ใช้หมายเลข 5 บิตในเวลา 0..31 จนกระทั่งไม่มีใครเหลือ
... join () ผลลัพธ์ของตัวสร้างบนตัวเลขสุ่มด้วยบิตที่ถูกต้อง
ด้วย Timeit สำหรับสตริง 32 อักขระเวลาคือ:
[('generate_with_random_choice', 28.92901611328125),
('generate_with_randbits', 20.0293550491333)]
... แต่สำหรับ 64 สายอักขระ randbits สูญเสีย;)
ฉันอาจจะไม่ใช้วิธีการนี้ในรหัสการผลิตเว้นแต่ฉันจะไม่ชอบเพื่อนร่วมงานของฉัน
แก้ไข: อัปเดตเพื่อให้เหมาะกับคำถาม (ตัวพิมพ์ใหญ่และตัวเลขเท่านั้น) และใช้ตัวดำเนินการบิต & & >> แทน% และ //
ฉันจะทำแบบนี้:
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
หรือเพียงแค่:
def rand_string(length, char_set=legals):
return ''.join( random.choice(char_set) for _ in range(length) )
ใช้ฟังก์ชั่น random.choice () ของ 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))
เอกสารอยู่ที่นี่http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.random.choice.html
บางครั้ง 0 (ศูนย์) & O (ตัวอักษร O) อาจสร้างความสับสน ดังนั้นฉันใช้
import uuid
uuid.uuid4().hex[:6].upper().replace('0','X').replace('O','Y')
>>> import string
>>> import random
ตรรกะต่อไปนี้ยังคงสร้างตัวอย่างสุ่ม 6 ตัวอักษร
>>> print ''.join(random.sample((string.ascii_uppercase+string.digits),6))
JT7K3Q
ไม่จำเป็นต้องคูณด้วย 6
>>> print ''.join(random.sample((string.ascii_uppercase+string.digits)*6,6))
TK82HK
สำหรับผู้ที่ชอบใช้งาน python:
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))))
มันสร้างตัววนซ้ำแบบไม่ จำกัด [infinite] ของการสุ่มลำดับโดยการสร้างลำดับแบบไม่ จำกัด ของสัญลักษณ์ที่สุ่มเลือกจากกลุ่มการให้แล้วแบ่งลำดับนี้เป็นส่วนความยาวที่เข้าร่วมแล้วควรทำงานกับลำดับใด ๆ ที่สนับสนุน getitem โดยค่าเริ่มต้นมันจะสร้างลำดับของตัวอักษรและตัวเลขแบบสุ่มแม้ว่าคุณจะสามารถปรับเปลี่ยนเพื่อสร้างสิ่งอื่น ๆ ได้อย่างง่ายดาย:
ตัวอย่างเช่นการสร้างอันดับของตัวเลขสุ่ม:
>>> 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)
หากคุณไม่ต้องการใช้รุ่นต่อไปคุณสามารถทำให้เรียกได้ว่า:
>>> irand_tuples = irand_seqs(xrange(10), join=tuple)
>>> make_rand_tuples = partial(next, irand_tuples)
>>> make_rand_tuples()
(1, 6, 2, 8, 1, 9)
หากคุณต้องการสร้างลำดับในการบินเพียงตั้งค่าการเข้าร่วมเพื่อระบุตัวตน
>>> irand_tuples = irand_seqs(xrange(10), join=identity)
>>> selections = next(irand_tuples)
>>> next(selections)
8
>>> list(selections)
[6, 3, 8, 2, 2]
ตามที่คนอื่น ๆ พูดถึงถ้าคุณต้องการความปลอดภัยเพิ่มขึ้นจากนั้นตั้งค่าฟังก์ชั่นการเลือกที่เหมาะสม:
>>> from random import SystemRandom
>>> rand_strs = irand_seqs(select=SystemRandom().choice)
'QsaDxQ'
ตัวเลือกเริ่มต้นคือchoice
สิ่งที่อาจเลือกสัญลักษณ์เดียวกันหลายครั้งสำหรับแต่ละชิ้นถ้าคุณต้องการให้สมาชิกเดิมเลือกมากที่สุดหนึ่งครั้งสำหรับแต่ละกลุ่ม
>>> 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]
เราใช้sample
เป็นตัวเลือกของเราเพื่อทำการเลือกอย่างสมบูรณ์ดังนั้นชิ้นจริง ๆ แล้วมีความยาว 1 และการเข้าร่วมเราเพียงแค่เรียกnext
สิ่งที่เรียกว่าอันถัดไปสร้างขึ้นอย่างสมบูรณ์รับตัวอย่างนี้ดูเหมือนยุ่งยากเล็กน้อยและมันเป็น ...
(1) สิ่งนี้จะให้ตัวพิมพ์ใหญ่และตัวเลขทั้งหมด:
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) หากคุณต้องการรวมตัวอักษรตัวเล็กในคีย์ของคุณในภายหลังนี่จะใช้งานได้:
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
นี่เป็นการตอบสนองของ Anurag Uniyal และสิ่งที่ฉันกำลังทำกับตัวเอง
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'
random.choice
ฟังก์ชั่นหยิบรายการที่สุ่มในรายการ นอกจากนี้คุณยังสร้างรายการเพื่อให้คุณสามารถเพิ่มตัวละครในfor
งบ ในตอนท้ายของ str คือ ['t', 'm', '2', 'J', 'U', 'Q', '0', '4', 'C', 'K'] แต่str = "".join(str)
ใช้เวลา 'tm2JUQ04CK'
ดูแลการที่ออกจากคุณกับ
หวังว่านี่จะช่วยได้!
range(num)
แทนและ STR 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="")
ความยาวของสตริงสามารถเปลี่ยนได้สำหรับลูปเช่นสำหรับ i ในช่วง (1, ความยาว) มันเป็นอัลกอริธึมที่เข้าใจง่าย มันใช้รายการเพื่อให้คุณสามารถทิ้งอักขระที่คุณไม่ต้องการ
ง่าย ๆ :
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
ฉันอยากจะแนะนำตัวเลือกต่อไปของคุณ:
import crypt
n = 10
crypt.crypt("any sring").replace('/', '').replace('.', '').upper()[-n:-1]
โหมดหวาดระแวง:
import uuid
import crypt
n = 10
crypt.crypt(str(uuid.uuid4())).replace('/', '').replace('.', '').upper()[-n:-1]
สองวิธี:
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))
เกณฑ์มาตรฐาน:
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)))
ผลผลิต:
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
ประสิทธิภาพของวิธีแรกดีกว่า
ฉันไปแล้วแม้ว่าคำตอบเกือบทั้งหมด แต่ไม่มีคำตอบใดที่ดูง่ายขึ้น ฉันอยากจะแนะนำให้คุณลองใช้รหัสผ่านห้องสมุดซึ่งโดยทั่วไปจะใช้ในการสร้างรหัสผ่านแบบสุ่ม
คุณสามารถสร้างสตริงสุ่มที่คุณเลือกความยาวเครื่องหมายวรรคตอนตัวเลขตัวอักษรและเล็ก
นี่คือรหัสสำหรับกรณีของคุณ:
from passgen import passgen
string_length = int(input())
random_string = passgen(length=string_length, punctuation=False, digits=True, letters=True, case='upper')
สร้างตัวอักษร 16 บิตประกอบด้วยรหัสตัวอักษรตัวเลข '_' และ '-'
os.urandom(16).translate((f'{string.ascii_letters}{string.digits}-_'*4).encode('ascii'))
ฉันกำลังดูคำตอบต่าง ๆ และใช้เวลาอ่านเอกสารความลับ
โมดูลลับใช้สำหรับสร้างหมายเลขสุ่มที่รัดกุมเหมาะสำหรับการจัดการข้อมูลเช่นรหัสผ่านการตรวจสอบบัญชีโทเค็นความปลอดภัยและความลับที่เกี่ยวข้อง
โดยเฉพาะอย่างยิ่งความลับควรใช้ในการตั้งค่าตัวสร้างตัวเลขสุ่มหลอกเริ่มต้นในโมดูลสุ่มซึ่งถูกออกแบบมาสำหรับการสร้างแบบจำลองและการจำลองไม่ใช่ความปลอดภัยหรือการเข้ารหัส
ดูเพิ่มเติมเกี่ยวกับสิ่งที่มีให้ฉันพบฟังก์ชั่นที่มีประโยชน์มากถ้าคุณต้องการเลียนแบบ ID เช่น Google Drive ID:
secret.token_urlsafe ([nbytes = None])
ส่งคืนสตริงข้อความแบบ URL ที่ปลอดภัยซึ่งประกอบด้วย nbytes Random ไบต์ ข้อความที่เข้ารหัส Base64 ดังนั้นโดยเฉลี่ยผลแต่ละไบต์ประมาณ1.3 ตัวอักษร หาก nbytes เป็นไม่มีหรือไม่ได้ให้มาจะใช้ค่าเริ่มต้นที่เหมาะสม
ใช้วิธีต่อไปนี้:
import secrets
import math
def id_generator():
id = secrets.token_urlsafe(math.floor(32 / 1.3))
return id
print(id_generator())
ส่งออก id ความยาว 32 ตัวอักษร:
joXR8dYbBDAHpVs5ci6iD-oIgPhkeQFk
ฉันรู้ว่าสิ่งนี้แตกต่างจากคำถามของ OP เล็กน้อย แต่ฉันคาดหวังว่ามันจะยังคงมีประโยชน์สำหรับคนจำนวนมากที่กำลังมองหากรณีการใช้งานแบบเดียวกับที่ฉันกำลังมองหา
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
ฉันพบว่าสิ่งนี้ง่ายกว่าและสะอาดกว่า
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
เพียงแค่เปลี่ยน 64 เพื่อเปลี่ยนความยาวเปลี่ยน CharacterPool เพื่อทำอัลฟ่าเพียงตัวอักษรตัวเลขหรือตัวเลขเท่านั้นหรือตัวละครแปลก ๆ หรืออะไรก็ตามที่คุณต้องการ