前几天接到一个密码强度判断的需求
● 规则1:大写字母,小写字母、数字,特殊字符,至少包含3种,长度不低于8位
● 规则2:不可以连续数字,至少3位(如:123、321)
● 规则3:不可以连续字母,至少3位(如:ABC、abc)
● 规则4:不可以连续键盘,至少3位(如QAZ、qaz)
● 规则5:不可用Jianshu1到Jianshu9;Ios1到Ios19
● 规则6:不能包含连续3位及以上相同字母或数字
其中规则1和规则6还是比较常见的,规则2和规则3也有很多,规则4倒是第一次遇到,一开始挺头疼的。规则5可以结合正则表达式解决。不废话了,直接看解决方法。
规则1:大写字母,小写字母、数字,特殊字符,至少包含3种,长度不低于8位
NSString * strongPassword = @"^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\W_!@#$%^&*`~()-+=]+$)(?![a-z0-9]+$)(?![a-z\W_!@#$%^&*`~()-+=]+$)(?![0-9\W_!@#$%^&*`~()-+=]+$)[a-zA-Z0-9\W_!@#$%^&*`~()-+=]{8,}$";
+ (BOOL) isString:(NSString *) str matchWith:(NSString *) regex {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
BOOL isOK = [predicate evaluateWithObject:str];
return isOK;
}
规则5:不可用Jianshu1到Jianshu9;Ios1到Ios19
if (([pwd containsString:@"Jianshu"] && pwd.length == 8) || ([pwd containsString:@"Ios"] && pwd.length == 4)) {
}else if ([pwd containsString:@"Ios1"] && pwd.length == 5){
}
NSString *jianPwd = @"^Jianshu[1-9]|Ios[1-9]";
NSString *iosPwd = @"^Ios1[0-9]";
NSString * strongPassword = @"^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![a-z0-9]+$)[a-zA-Z0-9]{8,}$";
+ (BOOL) isString:(NSString *) str matchWith:(NSString *) regex {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
BOOL isOK = [predicate evaluateWithObject:str];
return isOK;
}
规则6:不能包含连续3位及以上相同字母或数字
//字符串元素连续三个及以上相同
+(BOOL )containsThreeConsec:(NSString *)str{
NSMutableArray *strarr = [NSMutableArray array];
// 遍历字符串中的每个字符
for (NSUInteger i = 0; i < str.length; i++) {
// 提取每个字符并将其添加到数组中
NSString *charStr = [NSString stringWithFormat:@"%C", [str characterAtIndex:i]];
[strarr addObject:charStr];
}
// 遍历字符串(除了最后两个字符,因为我们需要检查当前字符和接下来的两个字符)
for (int i = 0; i < strarr.count - 2; i++) {
// 检查当前字符是否与接下来的两个字符相同
if ([strarr[i] isEqualToString:strarr[i+1]] && [strarr[i] isEqualToString:strarr[i+2]]) {
// 如果相同,则返回YES
return YES;
}
}
// 如果没有找到三个连续重复的字符,则返回NO
return NO;
}
规则2:不可以连续数字,至少3位(如:123、321)
规则3:不可以连续字母,至少3位(如:ABC、abc)
规则4:不可以连续键盘排列,至少3位(如QAZ、qaz)
这是三个写在一起了,统一都转换成ASCII码来判断,区分大小写,同时判断正序和倒序。键盘排列还区分横竖。其中键盘排列是把每一个字母都手动关联一个数字,q为100,同一横排数字+1,同一竖排数字+100。
//连续的数字或者字母,用ASCII码值十进制判断
//数字范围0-9是48-57,大写A-Z是65-90,小写a-z是97-122
//连续的键盘纵横排列,例如qwe.rfv
//filter参数:数字“num”,字母“char”,键盘排列:“ keyboard”
+(BOOL)containsThreeCoiled:(NSString *)str andFilter:(NSString *)filter{
// 将字符串转换为数组
NSMutableArray *strarr = [NSMutableArray array];
// 遍历字符串中的每个字符
for (NSUInteger i = 0; i < str.length; i++) {
// 提取每个字符并将其添加到数组中
NSString *charStr = [NSString stringWithFormat:@"%C", [str characterAtIndex:i]];
[strarr addObject:charStr];
}
NSInteger length = strarr.count;
// 遍历字符串(除了最后两个字符,因为我们需要检查当前字符及后续两个字符)
for (NSInteger i = 0; i < length - 2; i++) {
// 检查当前字符及其后续两个字符是否都是数字且连续
unichar acStr = [strarr[i] characterAtIndex:0];
unichar bcStr = [strarr[i+1] characterAtIndex:0];
unichar ccStr = [strarr[i+2] characterAtIndex:0];
NSInteger ac = [NSNumber numberWithUnsignedChar:acStr].integerValue;
NSInteger bc = [NSNumber numberWithUnsignedChar:bcStr].integerValue;
NSInteger cc = [NSNumber numberWithUnsignedChar:ccStr].integerValue;
//判断是否是数字或者大小写字母
if ([filter isEqualToString:@"num"]) { //数字判断
if ((ac >= 48 && ac <= 57)) {
if ((bc >= 48 && bc <= 57)) {
if ((cc >= 48 && cc <= 57)) {
if (( bc-1 == ac && ac == cc-2)) { //判断递增
return YES;
}else if (bc+1 == ac && ac == cc+2) { //判断递减
return YES;
}
}
}
}
}else{ //字母判断
if ((ac >= 65 && ac <= 90) || (ac >= 97 && ac <= 122)) {
if ((bc >= 65 && bc <= 90) || (bc >= 97 && bc <= 122)) {
if ((cc >= 65 && cc <= 90) || (cc >= 97 && cc <= 122)) {
if ([filter isEqualToString:@"keyboard"]) {//是否是连续键盘排列
//获取字母在键盘排列所关联的数字
NSInteger acASCIINum = [self getKeyboardRangeNum:ac];
NSInteger bcASCIINum = [self getKeyboardRangeNum:bc];
NSInteger ccASCIINum = [self getKeyboardRangeNum:cc];
if (( bcASCIINum-1 == acASCIINum && acASCIINum == ccASCIINum-2)) { //横向判断递增
return YES;
}else if (bcASCIINum+1 == acASCIINum && acASCIINum == ccASCIINum+2) { //横向判断递减
return YES;
}else if (( bcASCIINum-100 == acASCIINum && acASCIINum == ccASCIINum-200)) { //纵向判断递增
return YES;
}else if (bcASCIINum+100 == acASCIINum && acASCIINum == ccASCIINum+200) { //纵向判断递减
return YES;
}
}else{ //是否是连续字母
if (( bc-1 == ac && ac == cc-2)) { //判断递增
return YES;
}else if (bc+1 == ac && ac == cc+2) { //判断递减
return YES;
}
}
}
}
}
}
}
// 如果没有找到连续的三位或更多位数字或字母,则返回NO
return NO;
}
+(NSInteger )getKeyboardRangeNum:(NSInteger )ASCIINum{
if (ASCIINum == 81 || ASCIINum == 113) { //q
return 100;
}
if (ASCIINum == 87 || ASCIINum == 119) { //w
return 101;
}
if (ASCIINum == 69 || ASCIINum == 101) { //e
return 102;
}
if (ASCIINum == 82 || ASCIINum == 114) { //r
return 103;
}
if (ASCIINum == 84 || ASCIINum == 116) { //t
return 104;
}
if (ASCIINum == 89 || ASCIINum == 121) { //y
return 105;
}
if (ASCIINum == 85 || ASCIINum == 117) { //u
return 106;
}
if (ASCIINum == 73 || ASCIINum == 105) { //i
return 107;
}
if (ASCIINum == 79 || ASCIINum == 111) { //o
return 108;
}
if (ASCIINum == 80 || ASCIINum == 112) { //p
return 109;
}
if (ASCIINum == 65 || ASCIINum == 97) { //a
return 200;
}
if (ASCIINum == 83 || ASCIINum == 115) { //s
return 201;
}
if (ASCIINum == 68 || ASCIINum == 100) { //d
return 202;
}
if (ASCIINum == 70 || ASCIINum == 102) { //f
return 203;
}
if (ASCIINum == 71 || ASCIINum == 103) { //g
return 204;
}
if (ASCIINum == 72 || ASCIINum == 104) { //h
return 205;
}
if (ASCIINum == 74 || ASCIINum == 106) { //j
return 206;
}
if (ASCIINum == 75 || ASCIINum == 107) { //k
return 207;
}
if (ASCIINum == 76 || ASCIINum == 108) { //l
return 208;
}
if (ASCIINum == 90 || ASCIINum == 122) { //z
return 300;
}
if (ASCIINum == 88 || ASCIINum == 120) { //x
return 301;
}
if (ASCIINum == 67 || ASCIINum == 99) { //c
return 302;
}
if (ASCIINum == 86 || ASCIINum == 118) { //v
return 303;
}
if (ASCIINum == 66 || ASCIINum == 98) { //b
return 304;
}
if (ASCIINum == 78 || ASCIINum == 110) { //n
return 305;
}
if (ASCIINum == 77 || ASCIINum == 109) { //m
return 306;
}
return 0;
}