代碼搬運自Jonathan Zdziarski著《iOS應用安全攻防實戰》,這是本好書,讓我受益匪淺。
強壯的密碼一般遵循以下規則:
- 盡量長的密碼長度
- 包含大小寫字母
- 組合中包含數字
- 特殊字符,比如,#和標點
- 避免特定的鍵盤輸入模式,比如,水平劃過QWERTY鍵盤
- 避免使用在通話語言字典中可找到的單詞
- 不含日期或者其他結構化數據
我們可以寫一個簡單的密碼檢查方法,檢查密碼長度,是否包含大小寫混合和特殊符號,還可以測量兩次輸入的鍵盤距離。
具體實現
#include <stdio.h>
#include <string.h>
#include <sys/param.h>
#include <ctype.h>
#include <stdlib.h>
int key_distance(char a, char b) {
const char *qwerty_lc = "`1234567890-="
"qwertyuiop[]\\"
" asdfghjkl;' "
" zxcvbnm,./ ";
const char *qwerty_uc = "~!@#$%^&*()_+"
"QWERTYUIOP{}|"
" ASDFGHJKL:\" "
" ZXCVBNM<>? ";
int pos_a, pos_b, dist;
if(strchr(qwerty_lc, a))
pos_a = strchr(qwerty_lc, a) - qwerty_lc;
else if (strchr(qwerty_uc, a))
pos_a = strchr(qwerty_uc, a) - qwerty_uc;
else
return -2;
if (strchr(qwerty_lc, b))
pos_b = strchr(qwerty_lc, b) - qwerty_lc;
else if (strchr(qwerty_uc, b))
pos_b = strchr(qwerty_uc, b) - qwerty_uc;
else
return -1;
dist = abs((pos_a/13) - (pos_b)/13) /* 行距離 */
+ abs(pos_a % 13 - pos_b % 13); /* 列距離 */
return dist;
}
int score_passphrase(const char *passphrase) {
int total_score = 0;
int unit_score;
int distances[strlen(passphrase)];
int i;
/* 密碼長度 */
unit_score = strlen(passphrase) / 4;
total_score += MIN(3, unit_score);
/* 大寫字母 */
for (unit_score = i = 0; passphrase[i]; ++i) {
if (isupper(passphrase[i])) {
unit_score++;
}
}
total_score += MIN(3, unit_score);
/* 小寫字母 */
for (unit_score = i = 0; passphrase[i]; ++i) {
if (islower(passphrase[i])) {
unit_score++;
}
}
total_score += MIN(3, unit_score);
/* 數字 */
for (unit_score = i = 0; passphrase[i]; ++i) {
if (isdigit(passphrase[i])) {
unit_score++;
}
}
total_score += MIN(3, unit_score);
/* 特殊字符 */
for (unit_score = i = 0; passphrase[i]; ++i) {
if (!isalnum(passphrase[i])) {
unit_score++;
}
}
total_score += MIN(3, unit_score);
/* 鍵盤距離 */
distances[0] = 0;
for (unit_score = i = 0; passphrase[i]; ++i) {
if (passphrase[i+1]) {
int dist = key_distance(passphrase[i], passphrase[i+1]);
if (dist > 1) {
int j, exists = 0;
for (j=0; distances[j]; ++j) {
if (distances[j] == dist) {
exists = 1;
}
}
if (!exists) {
distances[j] = dist;
distances[j+1] = 0;
unit_score++;
}
}
}
}
total_score += MIN(3, unit_score);
return ((total_score / 18.0) * 100);
}
使用
結果為 0~100 的數,分數越高,密碼強度越強。
NSString *passWord = @"qwikdhksja*lkfh23dksahf1";
int score = score_passphrase([passWord UTF8String]);
NSLog(@"%d",score); //結果為72