CSP第35次_01:密码

题目背景

西西艾弗网对用户密码有一套安全级别评定标准。

题目描述

在西西艾弗网上,用户的密码是一个由大写字母(A-Z)、小写字母(a-z)、数字(0-9)和特殊字符(*#)共 6464 种字符组成的字符串。

根据复杂程度不同,密码安全度被分为高、中、低三档。

  • 高:由上述 6464 种字符组成,长度大于等于 66 个字符,包含字母、数字和特殊字符,同一个字符出现不超过 22 次;
  • 中:由上述 6464 种字符组成,长度大于等于 66 个字符,包含字母、数字和特殊字符,且未达到高安全度要求;
  • 低:由上述 6464 种字符组成,长度大于等于 66 个字符,且未达到中安全度要求;

小 P 为自己准备了 nn 个候选密码,试编写程序帮小 P 自动判别每个密码的安全级别。保证这 nn 个密码都至少满足低安全度要求,当安全度为高、中、低时分别输出 210 即可。

输入格式

从标准输入读入数据。

输入共 n+1n+1 行。

第一行包含一个正整数 nn,表示待判别的密码个数;

接下来 nn 行,每行一个字符串,表示一个安全度至少为低的候选密码。

输出格式

输出到标准输出。

输出共 nn 行,每行输出一个整数 210,表示对应密码的安全度。

样例输入

1
2
3
4
5
4
csp#ccsp
csp#ccsp2024
Csp#ccsp2024
CSP#2024

样例输出

1
2
3
4
0
1
2
2

样例解释

第一个密码不含数字,安全度为低;

第二个密码中小写字母 c 出现 33 次,安全度为中;

和第二个密码相比,第三个密码把一个小写字母 c 变为了大写,满足了高安全度要求;

第四个密码同样满足高安全度要求。

子任务

全部的测试数据满足 n≤100n≤100,且输入的每个字符串均不超过 2020 个字符。

题解

这道题很简单,主要是对于字符的判断(数字、大小写字母、特殊字符)。

使用正则表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def judge_security(u_pwd):
if re.search(r'[a-z]', u_pwd) or re.search(r'[A-Z]', u_pwd):
if re.search(r'[0-9]', u_pwd):
if re.search(r'[^a-zA-Z0-9]', u_pwd):
char_dict = Counter(u_pwd)
char_show_nums = list(char_dict.values())
for num in char_show_nums:
if num > 2:
return 1
return 2
else:
return 0
else:
return 0
else:
return 0

更简洁:

使用boolnotany

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def judge_security(u_pwd):          
# 判断密码中是否包含字母、数字和特殊字符
has_letter = bool(re.search(r'[a-zA-Z]', u_pwd))
has_digit = bool(re.search(r'[0-9]', u_pwd))
has_special = bool(re.search(r'[^a-zA-Z0-9]', u_pwd))

if not(has_letter and has_digit and has_special):
return 0

char_count = Counter(u_pwd)
if any(count > 2 for count in char_count.values()):
return 1
else:
return 2

知识点

字符判断

1、使用内置函数:

  • isnumeric():检查字符串是否只包含数字字符。
  • isalpha():检查字符串是否只包含字母。
  • isspace():检查字符串是否只包含空白字符(如空格、制表符、换行符等)。
  • ispunct():检查字符串是否只包含标点符号。
  • isalnum():检查字符串是否只包含字母和数字。
  • isupper() 方法判断是否为大写字母。
  • islower() 方法判断是否为小写字母。

2、使用正则表达式:

1
re.search(r'[a-zA-Z]', u_pwd) # 字母
1
re.search(r'[0-9]', u_pwd) # 数字
1
re.search(r'^[a-zA-Z0-9]', u_pwd) # 特殊字符

3、使用ASCII值:

1
2
3
4
5
6
if '0' <= char <= '9':
return "数字"
elif 'A' <= char <= 'Z' or 'a' <= char <= 'z':
return "字母"
else:
return "特殊字符"

re.search和re.match的区别

re.match 只能在起始位置匹配,而re.search可以扫描整个字符串并返回第一个成功的匹配

re.findall 方法可以找到所有满足匹配条件的结果,并以列表的形式返回

字符统计出现次数

1
from collections import Counter

主要功能:可以支持方便、快速的计数,将元素数量统计,然后计数并返回一个字典,键为元素,值为元素个数。