如何生成大小为N的字符串,由数字和大写英文字母组成,例如:
6个754z4英国U911K4型
如何生成大小为N的字符串,由数字和大写英文字母组成,例如:
6个754z4英国U911K4型
当前回答
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
其他回答
现在可以在这里使用一个新的库(python>=3.6)
from chancepy import Chance
random_string = Chance.string(length=10, pool="someLettersAndNumbers123")
import uuid
lowercase_str = uuid.uuid4().hex
lowercase_str是一个随机值,如“cea8b32e0934aae8c005a35d85a5c0”
uppercase_str = lowercase_str.upper()
上机匣_str为“CEA8B32E00934AAEA8C005A35D85A5C0”
对于那些喜欢功能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))))
它生成一个不定[无限]迭代器,由连接的随机序列组成,首先从给定的池中生成一个随机选择的符号的不定序列,然后将该序列分解为长度部分,然后进行连接,它应该与支持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)
如果您不想使用next for generation,您可以简单地将其设置为可调用:
>>> irand_tuples = irand_seqs(xrange(10), join=tuple)
>>> make_rand_tuples = partial(next, irand_tuples)
>>> make_rand_tuples()
(1, 6, 2, 8, 1, 9)
如果您想动态生成序列,只需将join设置为identity即可。
>>> 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,它获取下一个完全生成的块,当然这个示例看起来有点麻烦,而且它。。。
我在寻找不同的答案,并花时间阅读了秘密文件
机密模块用于生成适合于管理数据(如密码、帐户验证、安全令牌和相关机密)的加密强随机数。特别是,应优先使用秘密,而不是随机模块中的默认伪随机数生成器,其设计用于建模和模拟,而不是安全或密码学。
深入了解它所提供的功能,我发现如果你想模仿像Google Drive ID这样的ID,我会发现一个非常方便的功能:
secrets.token_urlsafe([nbytes=无])返回随机URL安全文本字符串,包含n字节随机字节。文本是Base64编码的,因此平均每个字节大约有1.3个字符。如果nbytes为None或未提供,则使用合理的默认值。
使用方法如下:
import secrets
import math
def id_generator():
id = secrets.token_urlsafe(math.floor(32 / 1.3))
return id
print(id_generator())
输出32个字符的长度id:
joXR8dYbBDAHpVs5ci6iD-oIgPhkeQFk
我知道这与OP的问题稍有不同,但我希望这对许多正在寻找与我相同用例的人仍然有帮助。
这个方法比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:更新以适应问题(仅限大写和数字),并使用按位运算符&和>>而不是%和//