前幾天接到一個(gè)密碼強(qiáng)度判斷的需求
● 規(guī)則1:大寫字母坟募,小寫字母、數(shù)字邑狸,特殊字符懈糯,至少包含3種,長度不低于8位
● 規(guī)則2:不可以連續(xù)數(shù)字推溃,至少3位(如:123昂利、321)
● 規(guī)則3:不可以連續(xù)字母,至少3位(如:ABC铁坎、abc)
● 規(guī)則4:不可以連續(xù)鍵盤蜂奸,至少3位(如QAZ、qaz)
● 規(guī)則5:不可用Jianshu1到Jianshu9硬萍;Ios1到Ios19
● 規(guī)則6:不能包含連續(xù)3位及以上相同字母或數(shù)字
其中規(guī)則1和規(guī)則6還是比較常見的扩所,規(guī)則2和規(guī)則3也有很多,規(guī)則4倒是第一次遇到朴乖,一開始挺頭疼的祖屏。規(guī)則5可以結(jié)合正則表達(dá)式解決助赞。不廢話了,直接看解決方法袁勺。
規(guī)則1:大寫字母雹食,小寫字母、數(shù)字期丰,特殊字符群叶,至少包含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;
}
規(guī)則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;
}
規(guī)則6:不能包含連續(xù)3位及以上相同字母或數(shù)字
//字符串元素連續(xù)三個(gè)及以上相同
+(BOOL )containsThreeConsec:(NSString *)str{
NSMutableArray *strarr = [NSMutableArray array];
// 遍歷字符串中的每個(gè)字符
for (NSUInteger i = 0; i < str.length; i++) {
// 提取每個(gè)字符并將其添加到數(shù)組中
NSString *charStr = [NSString stringWithFormat:@"%C", [str characterAtIndex:i]];
[strarr addObject:charStr];
}
// 遍歷字符串(除了最后兩個(gè)字符街立,因?yàn)槲覀冃枰獧z查當(dāng)前字符和接下來的兩個(gè)字符)
for (int i = 0; i < strarr.count - 2; i++) {
// 檢查當(dāng)前字符是否與接下來的兩個(gè)字符相同
if ([strarr[i] isEqualToString:strarr[i+1]] && [strarr[i] isEqualToString:strarr[i+2]]) {
// 如果相同,則返回YES
return YES;
}
}
// 如果沒有找到三個(gè)連續(xù)重復(fù)的字符埠通,則返回NO
return NO;
}
規(guī)則2:不可以連續(xù)數(shù)字赎离,至少3位(如:123、321)
規(guī)則3:不可以連續(xù)字母端辱,至少3位(如:ABC梁剔、abc)
規(guī)則4:不可以連續(xù)鍵盤排列,至少3位(如QAZ掠手、qaz)
這是三個(gè)寫在一起了憾朴,統(tǒng)一都轉(zhuǎn)換成ASCII碼來判斷狸捕,區(qū)分大小寫喷鸽,同時(shí)判斷正序和倒序。鍵盤排列還區(qū)分橫豎灸拍。其中鍵盤排列是把每一個(gè)字母都手動(dòng)關(guān)聯(lián)一個(gè)數(shù)字做祝,q為100,同一橫排數(shù)字+1,同一豎排數(shù)字+100鸡岗。
//連續(xù)的數(shù)字或者字母混槐,用ASCII碼值十進(jìn)制判斷
//數(shù)字范圍0-9是48-57,大寫A-Z是65-90轩性,小寫a-z是97-122
//連續(xù)的鍵盤縱橫排列声登,例如qwe.rfv
//filter參數(shù):數(shù)字“num”,字母“char”揣苏,鍵盤排列:“ keyboard”
+(BOOL)containsThreeCoiled:(NSString *)str andFilter:(NSString *)filter{
// 將字符串轉(zhuǎn)換為數(shù)組
NSMutableArray *strarr = [NSMutableArray array];
// 遍歷字符串中的每個(gè)字符
for (NSUInteger i = 0; i < str.length; i++) {
// 提取每個(gè)字符并將其添加到數(shù)組中
NSString *charStr = [NSString stringWithFormat:@"%C", [str characterAtIndex:i]];
[strarr addObject:charStr];
}
NSInteger length = strarr.count;
// 遍歷字符串(除了最后兩個(gè)字符悯嗓,因?yàn)槲覀冃枰獧z查當(dāng)前字符及后續(xù)兩個(gè)字符)
for (NSInteger i = 0; i < length - 2; i++) {
// 檢查當(dāng)前字符及其后續(xù)兩個(gè)字符是否都是數(shù)字且連續(xù)
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;
//判斷是否是數(shù)字或者大小寫字母
if ([filter isEqualToString:@"num"]) { //數(shù)字判斷
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"]) {//是否是連續(xù)鍵盤排列
//獲取字母在鍵盤排列所關(guān)聯(lián)的數(shù)字
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{ //是否是連續(xù)字母
if (( bc-1 == ac && ac == cc-2)) { //判斷遞增
return YES;
}else if (bc+1 == ac && ac == cc+2) { //判斷遞減
return YES;
}
}
}
}
}
}
}
// 如果沒有找到連續(xù)的三位或更多位數(shù)字或字母,則返回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;
}