Python密码生成器开发:如何生成排除指定ASCII值的随机标点符号
密码生成器标点符号生成问题解决方案
你的核心问题是直接随机选取33-152范围内的ASCII码时,会命中数字、字母等非标点字符,接下来给你两种解决思路,其中第一种更简洁可靠。
方法一:利用Python内置的string模块(推荐)
Python的string模块已经预定义了各类常用字符集合,包括标点符号string.punctuation,直接从这里随机选取就能避免踩ASCII范围的坑,代码更简洁易读:
import random import string do_they_want_the_pass = input("Would you like to create a random password?\nType 'yes' or 'no' ") if do_they_want_the_pass == "yes": print("Okay, let's go then, just give me 3 miliseconds") # 按要求生成各类字符:2大写、2小写、2数字、2标点 uppers = [random.choice(string.ascii_uppercase) for _ in range(2)] lowers = [random.choice(string.ascii_lowercase) for _ in range(2)] digits = [random.choice(string.digits) for _ in range(2)] puncs = [random.choice(string.punctuation) for _ in range(2)] # 合并所有字符并打乱顺序(提升密码随机性) password_chars = uppers + lowers + digits + puncs random.shuffle(password_chars) password = ''.join(password_chars) print(password)
方法二:实现你想要的循环判断逻辑
如果坚持用ASCII范围+排除集合的方式,需要修正排除集合的区间错误,并把集合转成set提升查询效率,然后循环生成直到拿到合法标点:
import random import string do_they_want_the_pass = input("Would you like to create a random password?\nType 'yes' or 'no' ") if do_they_want_the_pass == "yes": print("Okay, let's go then, just give me 3 miliseconds") # 生成大小写字母和数字 upper1 = chr(random.randint(65,90)) upper2 = chr(random.randint(65,90)) lower1 = chr(random.randint(97,122)) lower2 = chr(random.randint(97,122)) digit1 = str(random.randint(0,9)) digit2 = str(random.randint(0,9)) # 修正排除集合:range左闭右开,数字0-9对应ASCII48-57,所以用range(48,58) exclude_set = set(range(48,58)) | set(range(65,91)) | set(range(97,123)) | set(range(127,144)) | {150} # 循环生成合法标点 def get_valid_punctuation(): while True: ascii_code = random.randint(33,152) if ascii_code not in exclude_set: return chr(ascii_code) punc1 = get_valid_punctuation() punc2 = get_valid_punctuation() # 合并字符并打乱顺序 password_parts = [upper1, upper2, lower1, lower2, digit1, digit2, punc1, punc2] random.shuffle(password_parts) password = ''.join(password_parts) print(password)
关键细节说明
string模块的优势:string.ascii_uppercase、string.ascii_lowercase、string.digits、string.punctuation是Python官方维护的字符集合,覆盖所有常用对应字符,比自己手动维护ASCII范围更不容易出错。- 密码随机性优化:生成完所有字符后调用
random.shuffle()打乱顺序,避免固定的字符类型排列(比如先大写再小写再数字再标点),让密码更难被猜测。 - 排除集合的修正:你之前的
exclude_set1用了range(48,57),这会漏掉数字'9'的ASCII码57,因为range是左闭右开区间,正确的数字范围应该是range(48,58)。另外把排除集合转成set,in操作的查询效率比列表高很多,循环判断时更高效。
内容的提问来源于stack exchange,提问作者Jakub Mazurek
相关产品推荐
相关产品推荐

