在Python中用大写字母和数字随机生成string

我想要生成一个大小为N的string

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

  • 6U1S75
  • 4Z4UKK
  • U911K4

我怎样才能达到这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' 

它是如何工作的 ?

我们inputstring ,一个包含常用ASCII字符序列的模块, random一个处理随机生成的模块。

string.ascii_uppercase + string.digits只是连接代表大写ASCII字符和数字的字符列表:

 >>> string.ascii_uppercase 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' >>> string.digits '0123456789' >>> string.ascii_uppercase + string.digits 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' 

然后,我们使用列表理解来创build“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'] 

在上面的例子中,我们使用[创build列表,但是我们不在id_generator函数中,所以Python不会在内存中创build列表,而是一个接一个地生成元素( 这里更详细的介绍) 。

我们不会要求创buildstringelem “n”次,而是要求Python创build一个随机字符“n”,从字符序列中挑选出来:

 >>> random.choice("abcde") 'a' >>> random.choice("abcde") 'd' >>> random.choice("abcde") 'b' 

因此random.choice(chars) for _ in range(size)实际上是创build一个size字符序列。 从chars中随机选取的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'] 

然后我们只需要用一个空string连接它们,这样序列就变成了一个string

 >>> ''.join(['a', 'b', 'b']) 'abb' >>> [random.choice('abcde') for _ in range(3)] ['d', 'c', 'b'] >>> ''.join(random.choice('abcde') for _ in range(3)) 'dac' 

这个堆栈溢出quesion是目前谷歌“随机stringPython”的结果。 目前最高的答案是:

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

这是一个很好的方法,但随机PRNG不是密码安全的。 我想很多人研究这个问题将要产生随机stringencryption或密码。 你可以通过在上面的代码中做一些小改动来安全地做到这一点:

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

使用random.SystemRandom()而不是随机在* nix机器上使用/ dev / urandom和在Windows中使用CryptGenRandom() 。 这些是密​​码安全的PRNG。 在需要安全PRNG的应用程序中使用random.choice而不是random.SystemRandom().choice可能具有破坏性,考虑到这个问题的普及,我敢打赌已经犯了很多错误。

只需使用Python的内置uuid:

如果UUID适合您的用途,请使用内置的uuid软件包。

一线解决scheme:

import uuid; str(uuid.uuid4().get_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 

一个更简单,更快,但随机的方式是使用random.sample而不是分别select每个字母,如果允许n次重复,则将您的随机基数扩大n倍。

 import random import string char_set = string.ascii_uppercase + string.digits print ''.join(random.sample(char_set*6, 6)) 

注意:random.sample防止字符重用,乘以字符集的大小使得多次重复成为可能,但是它们仍然不太可能,那么它们是纯粹的随机select。 如果我们input一个长度为6的string,并且select'X'作为第一个字符,那么在select示例中,获得'X'的第二个字符的可能性与得到'X'的可能性相同第一个字符。 在random.sample实现中,获取'X'作为任何后续字符的几率只有6/7的机会,作为第一个字符

更快,更简单,更灵活的方法是使用strgen模块( pip install StringGenerator )。

用大写字母和数字生成一个6个字符的随机string:

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

在string中保证一个“特殊”字符:

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

可能没有数字(或大写字符)。

开发时间比上述任何解决scheme都快。 Ignacio的解决scheme是运行速度最快的解决scheme,使用Python标准库是正确的select。 但是你几乎不会以这种forms使用它。 您将需要使用SystemRandom(或者如果不可用则使用回退),确保所需的字符集被表示,使用unicode(或不),确保连续的调用产生一个唯一的string,使用一个string模块字符类的子集,这一切都需要更多的代码比提供的答案。 概括解决scheme的各种尝试都有一些局限性,即使用简单的模板语言,strgen解决更大的简洁性和performance力。

在PyPI上:

 pip install StringGenerator 

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

 import uuid str = uuid.uuid4().hex 

str是一个随机值,如'cea8b32e00934aaea8c005a35d85a5c0'

 uppercase_str = str.upper() 

uppercase_str'CEA8B32E00934AAEA8C005A35D85A5C0'

从Ignacio的答案,这与Python 2.6的工作:

 import random import string N=6 print ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N)) 

示例输出:

JQUBT2

如果你需要一个随机的string,而不是一个伪随机的 ,你应该使用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)) 

我以为没有人回答这个问题呢! 但是,嘿,这是我自己去的:

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

基于另一个堆栈溢出的答案, 最轻量级的方式来创build一个随机的string和一个随机的hex数字 ,比接受的答案更好的版本将是:

 ('%06x' % random.randrange(16**6)).upper() 

快多了。

这个方法比Ignacio发布的random.choice()方法稍微快一点,更麻烦一些。

它利用了伪随机algorithm的性质,对每个字符产生一个新的随机数,按位和移位的存储速度要快。

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

…创build一个发生器,在0..31时间内取出5位数字,直到没有剩下的数字

…用正确的位连接()发生器的结果在一个随机数上

有了Timeit,对于32个字符的string,时间是:

 [('generate_with_random_choice', 28.92901611328125), ('generate_with_randbits', 20.0293550491333)] 

…但是对于64个字符的string,randbits失去了;)

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

编辑:更新以适应问题(仅限大写和数字),并使用按位运算符&和>>代替%和//

从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的情况下,列表理解的速度要快于使用生成器expression式!

我会这样做:

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

对于那些喜欢function性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)))) 

它通过首先从给定池中随机select的符号生成一个不确定的序列,然后将这个序列分解成长度部分然后连接起来,产生一个不确定的[无限]迭代器,它是连接随机序列的,它应该支持任何支持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] 

正如其他人所提到的,如果您需要更多的安全性,请设置相应的selectfunction

 >>> from random import SystemRandom >>> rand_strs = irand_seqs(select=SystemRandom().choice) 'QsaDxQ' 

默认select器是可以为每个块select相同符号多次的select,但是如果您希望每个块最多select一个相同的成员,那么可以使用一个可能的用法:

 >>> 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作为我们的select器,做完整的select,所以块实际上是长度为1,并join我们只需调用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() 

使用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

 >>> 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函数在列表中选取一个随机条目。 您还可以创build一个列表,以便您可以在for语句中附加该字符。 最后str是['t','m','2','J','U','Q','0','4','C','K'],但str = "".join(str)照顾到这一点,给你留下'tm2JUQ04CK'

希望这可以帮助!

一个简单的:

 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 

导入string导入随机

下面的逻辑仍然会产生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 
 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 

我想build议你下一个选项:

 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] 

我发现这是更简单和更清洁。

 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只字母数字或数字或奇怪的字符或任何你想要的。

你可以使用代码

 var chars = "ABC123"; var random = new Random(); var result = new string( Enumerable.Repeat(chars, 7) //Change 7 to any number of characters you want in your outcome .Select(s => s[random.Next(s.Length)]) .ToArray()); textBox1.Text = result; 

这将随机吐出一个随机的7个字母数字模式,只需将7更改为您希望的任何数字,它将产生许多数字和/或字母。

另一种方式来写这个如下…

 var chars = "ABC123"; var stringChars = new char[7]; //Change 7 to any number of characters you want in your outcome var random = new Random(); for (int i = 0; i < stringChars.Length; i++) { stringChars[i] = chars[random.Next(chars.Length)]; } var finalString = new String(stringChars); textBox1.Text = finalstring;` 

我不确定如何添加限制,例如,如果有人知道如何限制结果有类似的东西,使它不允许某些数字和/或字母彼此相邻或重复,如获得“AAA123”这个请回复