如何生成大小为N的字符串,由数字和大写英文字母组成,例如:
6个754z4英国U911K4型
如何生成大小为N的字符串,由数字和大写英文字母组成,例如:
6个754z4英国U911K4型
当前回答
只需使用Python的内置uuid:
如果uuid适合您的用途,请使用内置的uuid包。
单线解决方案:
导入uuid;uuid.uuid4().hhex.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
其他回答
这个方法比Ignacio发布的random.choice()方法稍快,也稍令人讨厌。
它利用了伪随机算法的特性,按位和移位的存储体比为每个字符生成新的随机数更快。
# 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')
…创建一个生成器,该生成器每次从0..31取出5位数字,直到没有剩余
…join()生成器对随机数的结果与正确的位
使用Timeit,对于32个字符串,计时为:
[('generate_with_random_choice', 28.92901611328125),
('generate_with_randbits', 20.0293550491333)]
…但对于64个字符串,randbits会丢失;)
除非我真的不喜欢我的同事,否则我可能永远不会在生产代码中使用这种方法。
edit:更新以适应问题(仅限大写和数字),并使用按位运算符&和>>而不是%和//
两种方法:
import random, math
def randStr_1(字符:str,长度:int)->字符串:chars*=math.ceil(长度/长度(chars))chars=字母[0:length]chars=列表(chars)随机.洗牌(字符)返回“”.join(字符)def randStr_2(字符:str,长度:int)->字符串:返回“”.join(随机.选择(字符)用于范围(字符)中的i)基准:从timeit导入timeitsetup=“”导入操作系统,子流程,时间,字符串,随机,数学def randStr_1(字母:str,长度:int)->str:letters*=math.ceil(长度/长度(字母))letters=字母[0:长度]letters=列表(字母)随机洗牌(字母)return“”.join(字母)def randStr_2(字母:str,长度:int)->str:return“”.join(范围(长度)中i的随机选择(字母))"""打印(“方法1 vs方法2”,“,每次运行10次。”)长度为[101001000100005000010005001000000]:打印(长度,'字符:')eff1=timeit(“randStr_1(string.asci_letters,{})”.format(长度),setup=设置,数字=10)eff2=timeit(“randStr_2(string.ascii_letters,{})”.format(长度),setup=setup,number=10)打印(“\t{}s:{}s”。格式(圆形(eff1,6),圆形(eff2,6)))print('\tradio={}:{}\n'.格式(eff1/eff1,round(eff2/eff1,2)))输出:方法1与方法2,每次运行10次。100个字符:0.00141秒:0.00179秒比率=1.0:1.271000个字符:0.013857秒:0.017603秒比率=1.0:1.2710000个字符:0.13426秒:0.151169秒比率=1.0:1.1350000个字符:0.709403秒:0.855136秒比率=1.0:1.21100000个字符:1.360735秒:1.674584秒比率=1.0:1.23500000个字符:6.754923秒:7.160508秒比率=1.0:1.061000000个字符:11.232965秒:14.223914秒比率=1.0:1.27第一种方法的性能更好。
一种更快、更简单、更灵活的方法是使用strgen模块(pip-installStringGenerator)。
生成包含大写字母和数字的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标准库是正确的答案。但你几乎不会以这种形式使用它。你会希望使用SystemRandom(如果不可用,则回退),确保表示所需的字符集,使用unicode(或不使用),确保连续调用产生唯一字符串,使用字符串模块字符类之一的子集等。这一切都需要比提供的答案中更多的代码。各种推广解决方案的尝试都有局限性,strgen使用简单的模板语言以更简洁和表达能力解决了这些问题。
在PyPI上:
pip install StringGenerator
披露:我是strgen模块的作者。
一种无重复的随机生成器函数,使用一个集合来存储以前生成的值。注意,如果字符串或数量非常大,这将消耗一些内存,而且可能会稍微慢一点。发电机将在给定量或达到最大可能组合时停止。
代码:
#!/usr/bin/env python
from typing import Generator
from random import SystemRandom as RND
from string import ascii_uppercase, digits
def string_generator(size: int = 1, amount: int = 1) -> Generator[str, None, None]:
"""
Return x random strings of a fixed length.
:param size: string length, defaults to 1
:type size: int, optional
:param amount: amount of random strings to generate, defaults to 1
:type amount: int, optional
:yield: Yield composed random string if unique
:rtype: Generator[str, None, None]
"""
CHARS = list(ascii_uppercase + digits)
LIMIT = len(CHARS) ** size
count, check, string = 0, set(), ''
while LIMIT > count < amount:
string = ''.join(RND().choices(CHARS, k=size))
if string not in check:
check.add(string)
yield string
count += 1
for my_count, my_string in enumerate(string_generator(6, 20)):
print(my_count, my_string)
输出:
0 RS9N3P
1 S0GDGR
2 ZNBLFV
3 96FF97
4 38JJZ3
5 Q3214A
6 VLWNK1
7 QMT05E
8 X1ZFP0
9 MZF442
10 10L9AZ
11 GE8HIQ
12 S7PA43
13 MVLXO9
14 YX7Y0G
15 GIIKPF
16 3KCUQA
17 XHIXFV
18 BJQ5VG
19 HQF01Q
如果字符串始终需要包含字母和数字,请使用以下命令:
#!/usr/bin/env python
from typing import Generator
from random import SystemRandom as RND
from string import ascii_uppercase, digits
def string_generator(size: int = 2, amount: int = 1) -> Generator[str, None, None]:
"""
Return x random strings of a fixed length.
:param size: string length, defaults to 1
:type size: int, optional
:param amount: amount of random strings to generate, defaults to 1
:type amount: int, optional
:yield: Yield composed random string if unique
:rtype: Generator[str, None, None]
"""
if size < 2:
print(
'Since the string must contain letters and numbers,',
'its size must be at least two characters',
)
return
CHARS = list(ascii_uppercase + digits)
LIMIT = len(CHARS) ** size
count, check, string = 0, set(), ''
while LIMIT > count < amount:
while 1:
string = ''.join(RND().choices(CHARS, k=size))
if not (string.isalpha() or string.isnumeric()):
break
if string not in check:
check.add(string)
yield string
count += 1
for my_count, my_string in enumerate(string_generator(6, 20)):
print(my_count, my_string)
输出:
0 5JIITL
1 3W7AI1
2 8QMO10
3 ETHAI8
4 BLFPP9
5 50X2CC
6 1LI8WA
7 39CKET
8 R4IM0E
9 Q3KHGS
10 65CBIU
11 XTRHO4
12 N2XIGO
13 06VFCW
14 VE9MJ8
15 A9ADHK
16 Y5ROJ0
17 OH7EJF
18 TQ709S
19 P0DDNJ
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