如何生成大小为N的字符串,由数字和大写英文字母组成,例如:

6个754z4英国U911K4型


当前回答

一种无重复的随机生成器函数,使用一个集合来存储以前生成的值。注意,如果字符串或数量非常大,这将消耗一些内存,而且可能会稍微慢一点。发电机将在给定量或达到最大可能组合时停止。

代码:

#!/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

其他回答

我在寻找不同的答案,并花时间阅读了秘密文件

机密模块用于生成适合于管理数据(如密码、帐户验证、安全令牌和相关机密)的加密强随机数。特别是,应优先使用秘密,而不是随机模块中的默认伪随机数生成器,其设计用于建模和模拟,而不是安全或密码学。

深入了解它所提供的功能,我发现如果你想模仿像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的问题稍有不同,但我希望这对许多正在寻找与我相同用例的人仍然有帮助。

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

现在可以在这里使用一个新的库(python>=3.6)

from chancepy import Chance

random_string = Chance.string(length=10, pool="someLettersAndNumbers123")

我会这样做:

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

两种方法:

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第一种方法的性能更好。