题目链接

密码安全等级

题目描述

根据一系列规则为给定的密码计算一个安全分数,并根据分数评定其安全等级。

计分规则

  1. 密码长度

    • 个字符: 5 分
    • 个字符: 10 分
    • 个字符: 25 分
  2. 字母

    • 没有字母: 0 分
    • 全都是小写或全都是大写: 10 分
    • 大小写混合: 20 分
  3. 数字

    • 没有数字: 0 分
    • 1 个数字: 10 分
    • 个数字: 20 分
  4. 符号

    • 没有符号: 0 分
    • 1 个符号: 10 分
    • 个符号: 25 分
  5. 奖励 (取最高奖励,不累加)

    • 字母和数字: +2 分
    • 字母、数字和符号: +3 分
    • 大小写字母、数字和符号: +5 分

等级划分

  • : 非常安全 (VERY_SECURE)
  • : 安全 (SECURE)
  • : 非常强 (VERY_STRONG)
  • : 强 (STRONG)
  • : 一般 (AVERAGE)
  • : 弱 (WEAK)
  • : 非常弱 (VERY_WEAK)

解题思路

这是一个纯粹的模拟题,核心在于将题目中描述的计分规则准确地翻译成代码。我们需要设计一个函数或一段逻辑,能够 meticulously 地检查密码的各项指标,并累加分数。

算法流程

  1. 预处理

    • 读取输入的密码字符串。
    • 遍历一次字符串,统计以下信息:
      • 密码的 length (总长度)。
      • lower_case_count (小写字母个数)。
      • upper_case_count (大写字母个数)。
      • digit_count (数字个数)。
      • symbol_count (符号个数)。
  2. 分项计分

    • 初始化 total_score = 0
    • 长度分:根据 length 的值,使用 if-else 判断,将 5, 10, 或 25 加到 total_score
    • 字母分
      • 如果 lower_case_count > 0upper_case_count > 0,则为大小写混合,加 20 分。
      • 如果 lower_case_count > 0upper_case_count > 0 (但不满足上一条),则为单一大小写,加 10 分。
      • 否则,没有字母,加 0 分。
    • 数字分:根据 digit_count 的值 (0, 1, 或 >1),将 0, 10, 或 20 加到 total_score
    • 符号分:根据 symbol_count 的值 (0, 1, 或 >1),将 0, 10, 或 25 加到 total_score
    • 奖励分
      • 设置一些布尔标记,如 has_letter, has_digit, has_symbol, has_mixed_case
      • 这是一个有优先级的奖励,所以从最高奖励开始判断:
        • 如果 has_mixed_casehas_digithas_symbol,加 5 分。
        • 否则,如果 has_letterhas_digithas_symbol,加 3 分。
        • 否则,如果 has_letterhas_digit,加 2 分。
  3. 评定等级

    • 根据最终的 total_score,使用 if-else 从高到低判断其所属的区间,并输出对应的安全等级字符串。

代码

#include <iostream>
#include <string>
#include <cctype>

using namespace std;

// 检查字符是否为符号
bool isSymbol(char c) {
    return !isalnum(c);
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    string password;
    while (cin >> password) {
        int score = 0;
        int len = password.length();
        int lower_count = 0, upper_count = 0, digit_count = 0, symbol_count = 0;

        for (char c : password) {
            if (islower(c)) lower_count++;
            else if (isupper(c)) upper_count++;
            else if (isdigit(c)) digit_count++;
            else symbol_count++;
        }

        // 1. 长度分
        if (len <= 4) score += 5;
        else if (len <= 7) score += 10;
        else score += 25;

        // 2. 字母分
        if (lower_count > 0 && upper_count > 0) score += 20;
        else if (lower_count > 0 || upper_count > 0) score += 10;

        // 3. 数字分
        if (digit_count == 1) score += 10;
        else if (digit_count > 1) score += 20;

        // 4. 符号分
        if (symbol_count == 1) score += 10;
        else if (symbol_count > 1) score += 25;

        // 5. 奖励分
        bool has_letter = (lower_count > 0 || upper_count > 0);
        bool has_mixed = (lower_count > 0 && upper_count > 0);
        bool has_digit = (digit_count > 0);
        bool has_symbol = (symbol_count > 0);

        if (has_mixed && has_digit && has_symbol) score += 5;
        else if (has_letter && has_digit && has_symbol) score += 3;
        else if (has_letter && has_digit) score += 2;

        // 评定等级
        if (score >= 90) cout << "VERY_SECURE" << endl;
        else if (score >= 80) cout << "SECURE" << endl;
        else if (score >= 70) cout << "VERY_STRONG" << endl;
        else if (score >= 60) cout << "STRONG" << endl;
        else if (score >= 50) cout << "AVERAGE" << endl;
        else if (score >= 25) cout << "WEAK" << endl;
        else cout << "VERY_WEAK" << endl;
    }

    return 0;
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) {
            String password = sc.nextLine();
            int score = 0;
            int len = password.length();
            int lowerCount = 0, upperCount = 0, digitCount = 0, symbolCount = 0;

            for (char c : password.toCharArray()) {
                if (Character.isLowerCase(c)) lowerCount++;
                else if (Character.isUpperCase(c)) upperCount++;
                else if (Character.isDigit(c)) digitCount++;
                else symbolCount++;
            }

            // 1. 长度分
            if (len <= 4) score += 5;
            else if (len <= 7) score += 10;
            else score += 25;

            // 2. 字母分
            if (lowerCount > 0 && upperCount > 0) score += 20;
            else if (lowerCount > 0 || upperCount > 0) score += 10;

            // 3. 数字分
            if (digitCount == 1) score += 10;
            else if (digitCount > 1) score += 20;

            // 4. 符号分
            if (symbolCount == 1) score += 10;
            else if (symbolCount > 1) score += 25;

            // 5. 奖励分
            boolean hasLetter = (lowerCount > 0 || upperCount > 0);
            boolean hasMixed = (lowerCount > 0 && upperCount > 0);
            boolean hasDigit = (digitCount > 0);
            boolean hasSymbol = (symbolCount > 0);

            if (hasMixed && hasDigit && hasSymbol) score += 5;
            else if (hasLetter && hasDigit && hasSymbol) score += 3;
            else if (hasLetter && hasDigit) score += 2;

            // 评定等级
            if (score >= 90) System.out.println("VERY_SECURE");
            else if (score >= 80) System.out.println("SECURE");
            else if (score >= 70) System.out.println("VERY_STRONG");
            else if (score >= 60) System.out.println("STRONG");
            else if (score >= 50) System.out.println("AVERAGE");
            else if (score >= 25) System.out.println("WEAK");
            else System.out.println("VERY_WEAK");
        }
    }
}
import sys

def solve():
    for line in sys.stdin:
        password = line.strip()
        if not password:
            continue

        score = 0
        length = len(password)
        lower_count, upper_count, digit_count, symbol_count = 0, 0, 0, 0

        for char in password:
            if 'a' <= char <= 'z':
                lower_count += 1
            elif 'A' <= char <= 'Z':
                upper_count += 1
            elif '0' <= char <= '9':
                digit_count += 1
            else:
                symbol_count += 1

        # 1. 长度分
        if length <= 4:
            score += 5
        elif length <= 7:
            score += 10
        else:
            score += 25

        # 2. 字母分
        if lower_count > 0 and upper_count > 0:
            score += 20
        elif lower_count > 0 or upper_count > 0:
            score += 10

        # 3. 数字分
        if digit_count == 1:
            score += 10
        elif digit_count > 1:
            score += 20

        # 4. 符号分
        if symbol_count == 1:
            score += 10
        elif symbol_count > 1:
            score += 25
            
        # 5. 奖励分
        has_letter = (lower_count > 0 or upper_count > 0)
        has_mixed = (lower_count > 0 and upper_count > 0)
        has_digit = (digit_count > 0)
        has_symbol = (symbol_count > 0)

        if has_mixed and has_digit and has_symbol:
            score += 5
        elif has_letter and has_digit and has_symbol:
            score += 3
        elif has_letter and has_digit:
            score += 2

        # 评定等级
        if score >= 90:
            print("VERY_SECURE")
        elif score >= 80:
            print("SECURE")
        elif score >= 70:
            print("VERY_STRONG")
        elif score >= 60:
            print("STRONG")
        elif score >= 50:
            print("AVERAGE")
        elif score >= 25:
            print("WEAK")
        else:
            print("VERY_WEAK")

solve()

算法及复杂度

  • 算法:模拟

  • 时间复杂度,其中 是输入密码的长度。我们需要遍历一次密码字符串来统计各类字符的数量,后续的计分和评级都是常数时间操作。

  • 空间复杂度。除了存储输入的密码字符串外,我们只需要有限的几个变量来存储计数和分数,因此空间复杂度是常数。