diff --git a/apps/common/utils/random.py b/apps/common/utils/random.py index 267de8d22..166453da6 100644 --- a/apps/common/utils/random.py +++ b/apps/common/utils/random.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # import random +import secrets import socket import string import struct @@ -18,31 +19,24 @@ def random_ip(): def random_string(length: int, lower=True, upper=True, digit=True, special_char=False, symbols=string_punctuation): - random.seed() - args_names = ['lower', 'upper', 'digit'] - args_values = [lower, upper, digit] - args_string = [string.ascii_lowercase, string.ascii_uppercase, string.digits] - args_string_map = dict(zip(args_names, args_string)) - kwargs = dict(zip(args_names, args_values)) - kwargs_keys = list(kwargs.keys()) - kwargs_values = list(kwargs.values()) - args_true_count = len([i for i in kwargs_values if i]) + if not any([lower, upper, digit]): + raise ValueError('At least one of `lower`, `upper`, `digit` must be `True`') + if length < 4: + raise ValueError('The length of the string must be greater than 3') - assert any(kwargs_values), f'Parameters {kwargs_keys} must have at least one `True`' - assert length >= args_true_count, f'Expected length >= {args_true_count}, bug got {length}' - - chars = ''.join([args_string_map[k] for k, v in kwargs.items() if v]) - password = list(random.choice(chars) for i in range(length)) + chars_map = ( + (lower, string.ascii_lowercase), + (upper, string.ascii_uppercase), + (digit, string.digits), + ) + chars = ''.join([i[1] for i in chars_map if i[0]]) + texts = list(secrets.choice(chars) for __ in range(length)) if special_char: - special_num = length // 16 + 1 - special_index = [] - for i in range(special_num): - index = random.randint(1, length - 1) - if index not in special_index: - special_index.append(index) - for i in special_index: - password[i] = random.choice(symbols) + symbol_num = length // 16 + 1 + symbol_index = random.choices(list(range(1, length - 1)), k=symbol_num) + for i in symbol_index: + texts[i] = secrets.choice(symbols) - password = ''.join(password) - return password + text = ''.join(texts) + return text