具有大写字母和数字的随机字符串生成


1335

我想生成一个大小为N的字符串。

它应该由数字和大写英文字母组成,例如:

  • 6U1S75
  • 4Z4UKK
  • U911K4

我如何以pythonic方式实现这一目标?


11
这是一个非常受欢迎的问题。我希望专家会增加他的作为在这些随机数的唯一性的前3名的答案,即对于字符串大小范围的碰撞概率,说从6到16
用户

8
@buffer很容易计算可能的组合数。10个数字+ 26个字母= 36个可能的字符,以6的幂(字符串的长度)大约等于20亿。对于随机值,我的经验法则是“如果我为地球上的每个人类生成值,那么每个值可以有多少个值?”。在这种情况下,每个人的值会小于一个值,因此,如果要识别用户或对象,则字符太少。一种选择是添加小写字母,使您的排名变为62 ^ 6 =接近570亿唯一值。
布利克斯(Blixt)2015年

1
尽管想想世界人口似乎很愚蠢,但这只是因为您想要一个巨大的缓冲区来潜在的冲突。请参阅生日问题:en.wikipedia.org/wiki/Birthday_problem
Blixt 2015年

1
@buffer,那么您将对此答案感兴趣。
Anish Ramaswamy 2015年

这不应该重命名为“加密安全的随机字符串生成...”吗?
smci

Answers:


2539

一行回答:

''.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'

然后,我们使用列表推导创建“ 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'

7
@jorelli:这不是列表理解;这是一个生成器表达式。
伊格纳西奥·巴斯克斯

2
@joreilli:我在答案中添加了一个简短的注释,并提供了有关可迭代,列表理解,生成器以及最终yield关键字的更详细答案的链接。
e-satis

1
我将替换rangexrange
2013年

1
很有用。有趣的是,Django正在使用这段代码来生成密码和CSRF令牌。尽管您应该替换randomrandom.SystemRandom()github.com/django/django/blob/…– 2014
用户

1
@ Chiel92,random.sample创建样本时无需替换,换句话说,不可能重复字符,这不在OP的要求中。我认为这对于大多数应用程序不是理想的。
医师2014年

557

该堆栈溢出问题是“随机字符串Python”在Google上当前排名最高的结果。当前的最佳答案是:

''.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()的,而不是在* nix机器只是随机使用/ dev / urandom的,并CryptGenRandom()在Windows中。这些是加密安全的PRNG。在需要安全PRNG的应用程序中使用random.choice代替random.SystemRandom().choice可能会造成灾难性的后果,并且鉴于这个问题的普遍性,我敢打赌,这个错误已经犯了很多遍了。

如果您使用的是python3.6或更高版本,则可以使用MSeifert的答案中提到的新的secrets模块:

''.join(secrets.choice(string.ascii_uppercase + string.digits) for _ in range(N))

该模块文档还讨论了生成安全令牌最佳实践的便捷方法。


3
是的,的官方标准库random已发出警告:“ 警告:出于安全目的,请勿使用此模块的伪随机数生成器。如果需要加密安全的伪随机数生成器,请使用os.urandom()或SystemRandom。 ” 这是参考: random.SystemRandomos.urandom
lord63。j 2015年

4
好答案。小提示:您将其更改为string.uppercase根据区域设置可能导致意外结果。在涉及编码的情况下,使用string.ascii_uppercase(或string.ascii_letters + string.digits用base62代替base36)更安全。
布利克斯(Blixt),2015年

小笔记-最好使用xrange而不是range后者,因为后者会生成一个内存列表,而前者会创建迭代器。
guyarad '16

2
随机st会永远是唯一的吗?我想使用主键。
shakthydoss

3
@ shakthydoss:不。它可以返回“ AAA000”(它是一个随机字符串)和下一个“ AAA000”(它也是一个随机字符串)。您必须显式添加唯一性检查。
usr2564301

189

只需使用Python的内置uuid:

如果您可以使用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

14
+1对于问题的思考。也许您可以简要解释一下uuid1和uuid4之间的区别。
Thomas Ahle 2014年

1
如果我连续三次执行uuid1,我会得到:d161fd16-ab0f-11e3-9314-00259073e4a8,d3535b56-ab0f-11e3-9314-00259073e4a8,d413be32-ab0f-11e3-9314-00259073e4a8,它们似乎都相似(前8个字符不同,其余字符相同)。uuid4并非如此-Chase
Roberts

9
uui1:根据主机ID,序列号和当前时间生成UUID。uuid4:生成随机UUID。
Bijan 2014年

7
如果要跳过字符串强制转换和连字符替换,只需调用my_uuid.get_hex()或uuid.uuid4()。get_hex(),它就会返回从没有连字符的uuid生成的字符串。
dshap 2014年

8
截断UUID是个好主意吗?取决于string_length碰撞的大小,可能要考虑碰撞的可能性。
用户

44

一种更简单,更快速但稍微少一点的随机方式是使用random.sample而不是分别选择每个字母,如果允许n次重复,则将您的随机基础扩大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”作为第二个字符的几率相同第一个字符。在random.sample实现中,将“ X”作为任何后续字符的几率仅为将其作为第一个字符的机会的6/7


8
这种方法还不错,但是它不如分别选择每个字符那么随意,因为sample您永远不会两次列出相同的字符。当然,它也不会N超过36
bobince 2010年

对于给定的用例(如果没有可以重复的话),我会说这仍然是最好的解决方案。
Anurag Uniyal,2010年

3
其中一个例子有重复,因此我怀疑他是否希望禁止重复。
Mark Byers 2010年

5
如果random.sample防止重复使用的字符,字符集的大小乘使得多次重复可能的,但他们仍然不太可能那么他们是在一个纯随机的选择。如果我们选择长度为6的字符串,并选择“ X”作为第一个字符,则在选择示例中,第二个字符获得“ X”的几率与获得“ X”作为第二个字符的几率相同第一个字符。在random.sample实现中,将“ X”作为任何后续字符的几率仅为将其作为第一个字符的机会的5/6。
pcurry 2013年

1
在生成的字符串中移动时,重复获得特定字符的机会会下降。从26个大写字母加10个数字生成6个字符的字符串,独立地随机选择每个字符,任何特定的字符串都以频率1 /(36 ^ 6)出现。生成“ FU3WYE”和“ XXXXXX”的机会是相同的。在示例实现中,生成'XXXXXX'的机会为(1 /(36 ^ 6))*((6/6)*(5/6)*(4/6)*(3/6)*(2 / 6)*(1/6))归因于random.sample的非替换功能。在示例实施中,“ XXXXXX”的可能性降低了324倍。
2013年

32
import uuid
lowercase_str = uuid.uuid4().hex  

lowercase_str 是一个像 'cea8b32e00934aaea8c005a35d85a5c0'

uppercase_str = lowercase_str.upper()

uppercase_str'CEA8B32E00934AAEA8C005A35D85A5C0'


2
uppercase_str[:N+1]
Yajo

@Yajo是的,我们可以限制使用切片
Savad KP

2
@Yajo:不,您不想切片十六进制值。与全部大写字母和数字相比,您可以删除熵。也许可以用base32编码该值(熵从36 ** n稍微降低到32 ** n,但仍然好于16 ** n)。
马丁·彼得斯

19

执行此操作的更快,更轻松,更灵活的方法是使用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标准库的正确答案。但是您几乎不会以这种形式使用它。您将要使用SystemRandom(如果不可用,则使用备用版本),确保表示所需的字符集,使用(或不使用unicode),确保连续的调用产生唯一的字符串,使用字符串模块字符类之一的子集,等等。这比提供的答案需要更多的代码。概括解决方案的各种尝试都具有局限性,strgen使用简单的模板语言可以以更高的简洁性和更高的表达力来解决。

在PyPI上:

pip install StringGenerator

披露:我是strgen模块的作者。


12

从Python 3.6开始,如果需要加密secrets模块,则应使用模块而不是模块(否则,此答案与@Ignacio Vazquez-Abrams的答案相同):random

from secrets import choice
import string

''.join([choice(string.ascii_uppercase + string.digits) for _ in range(N)])

还有一点需要注意:列表理解str.join比使用生成器表达式要快!



9

如果您需要一个随机字符串而不是随机字符串,则应使用它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))

3
os.urandom伪随机怎么不?可能正在使用更好的算法来生成更随机的数字,但它仍然是伪随机的。
蒂洛2012年

@Tyilo,我知道之间的差异/dev/random/dev/urandom。问题是,/dev/random当没有足够的熵限制其有用性时会阻塞。对于一个时间垫 /dev/urandom来说还不够,但是我认为它比伪随机方法要好。
约翰·拉鲁伊

1
我会说/dev/random/dev/urandom都是伪随机的,但这可能取决于您的定义。
Tyilo

9

我以为还没有人回答这个大声笑!但是,嘿,这是我自己做的:

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))], "")

4
我不会对此表示反对,但是我认为对于这样一个简单的任务而言,它太复杂了。返回表达式是一个怪物。简单胜于复杂。
卡尔·史密斯

12
@CarlSmith,是的,确实,我的解决方案似乎对这项任务有些矫kill过正,但是我知道其他更简单的解决方案,只是希望找到一个替代途径来获得一个好的答案。没有自由,创造力就处于危险之中,因此我继续发表。
nemesisfixx 2012年

7

与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个字符串,randbit会失败;)

除非我真的不喜欢我的同事,否则我可能永远不会在生产代码中使用这种方法。

编辑:已更新为适合该问题(仅适用于大写和数字),并使用按位运算符&和>>代替%和//


5

我会这样:

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) )

5

使用Numpy的random.choice()函数

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


1
为什么我应该使用numpy random而不是python stdlib random?
Pax0r

因为它允许在参数中使用更多选项,例如长度,可变概率和带替换​​的选择。
Mudit Jain

5

有时0(零)和O(字母O)可能会造成混淆。所以我用

import uuid
uuid.uuid4().hex[:6].upper().replace('0','X').replace('O','Y')

4
>>> 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

3
但是此变体将强制所有字符都不同。如果N大于len(string.ascii_uppercase + string.digits),它将不起作用
MarSoft

3

对于那些喜欢使用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)

如果要动态生成序列,只需将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该连接,我们只需调用即可提取下一个完全生成的块,当然,这个示例似乎有点麻烦,而且它是...


3

(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  

3

这是对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()

2
>>> 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可以是string str += random.choice(chars)
萨什克2014年

2
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

2
尽管此代码可以回答问题,但是提供有关为什么和/或如何回答问题的其他上下文将大大提高其长期价值。请编辑您的答案以添加一些说明。
Toby Speight,

2
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="")

在这里,可以在for循环中更改字符串的长度,即在range(1,length)中的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

0

我想建议您下一个选择:

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]

0

两种方法:

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

第一种方法的性能更好。


0

我已经回答了几乎所有答案,但是看起来都没有那么容易。我建议您尝试使用passgen库,该库通常用于创建随机密码。

您可以生成随机字符串,长度,标点,数字,字母大小写。

这是您的情况的代码:

from passgen import passgen
string_length = int(input())
random_string = passgen(length=string_length, punctuation=False, digits=True, letters=True, case='upper')

0

生成随机的16字节ID包含字母,数字,“ _”和“-”

os.urandom(16).translate((f'{string.ascii_letters}{string.digits}-_'*4).encode('ascii'))


-1
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

-2

我发现这更简单,更清洁。

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以仅执行alpha字母数字或仅数字或奇怪字符或任何您想要的操作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.