某線上判題系統(OJ)要求實作密碼強度分級邏輯。允許字元集包含四大類:
@ - _ # ~| 等級 | 條件 |
|---|---|
| Best | 長度 ≥ 16,且四類字元全包含,且每類至少 2 個不同字元 |
| Strong | 不符合 Best,但長度 ≥ 10,且四類字元全包含 |
| Medium | 不符合 Best/Strong,但長度 ≥ 8,且至少包含三類字元 |
| Weak | 其餘情況 |
單純計數不足,必須去重。解法:為每類字元建立布林陣列或位元遮罩,標記出現過的字元,最後統計被標記的數量。
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#define MAX_LEN 100
int main(void) {
char pwd[MAX_LEN];
if (fgets(pwd, MAX_LEN, stdin) == NULL) return 0;
pwd[strcspn(pwd, "\n")] = '\0'; // 移除換行
bool has_upper[26] = {false}, has_lower[26] = {false};
bool has_digit[10] = {false}, has_special[256] = {false};
int upper_cnt = 0, lower_cnt = 0, digit_cnt = 0, special_cnt = 0;
int len = strlen(pwd);
for (int i = 0; i < len; ++i) {
char c = pwd[i];
if (c >= 'A' && c <= 'Z') {
if (!has_upper[c - 'A']) { has_upper[c - 'A'] = true; upper_cnt++; }
} else if (c >= 'a' && c <= 'z') {
if (!has_lower[c - 'a']) { has_lower[c - 'a'] = true; lower_cnt++; }
} else if (c >= '0' && c <= '9') {
if (!has_digit[c - '0']) { has_digit[c - '0'] = true; digit_cnt++; }
} else { // @ - _ # ~
if (!has_special[(unsigned char)c]) { has_special[(unsigned char)c] = true; special_cnt++; }
}
}
int categories = (upper_cnt > 0) + (lower_cnt > 0) + (digit_cnt > 0) + (special_cnt > 0);
if (len >= 16 && categories == 4 &&
upper_cnt >= 2 && lower_cnt >= 2 && digit_cnt >= 2 && special_cnt >= 2) {
printf("%d Best\n", len);
} else if (len >= 10 && categories == 4) {
printf("%d Strong\n", len);
} else if (len >= 8 && categories >= 3) {
printf("%d Medium\n", len);
} else {
printf("%d Weak\n", len);
}
return 0;
}
fgets 讀取整行,避免 scanf 遇空白截斷categories 利用布林值自動轉 0/1 相加輸入: abcdXYZ1234@-_-# 輸出: 16 Best 輸入: 12345678abcdefghXYZ 輸出: 19 Medium (缺特殊符號,僅三類) 輸入: aX1@ 輸出: 4 Weak