代码搬运自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