#import <Foundation/Foundation.h> typedef enum { IdentifierTypeKnown = 0, IdentifierTypeZipCode, //1 IdentifierTypeEmail, //2 IdentifierTypePhone, //3 IdentifierTypeUnicomPhone, //4 IdentifierTypeQQ, //5 IdentifierTypeNumber, //6 IdentifierTypeString, //7 IdentifierTypeIdentifier, //8 IdentifierTypePassort, //9 IdentifierTypeCreditNumber, //10 IdentifierTypeBirthday, //11 }IdentifierType; @interface IdentifierValidator : NSObject { } + (BOOL) isValid:(IdentifierType) type value:(NSString*) value; @end #import "IdentifierValidator.h" #import "NSString+ITTAdditions.h" int getIndex (char ch); BOOL isNumber (char ch); int getIndex (char ch) { if ((ch >= '0'&& ch <= '9')||(ch >= 'a'&& ch <= 'z')|| (ch >= 'A' && ch <= 'Z')|| ch == '_') { return 0; } if (ch == '@') { return 1; } if (ch == '.') { return 2; } return -1; } BOOL isNumber (char ch) { if (!(ch >= '0' && ch <= '9')) { return FALSE; } return TRUE; } @implementation IdentifierValidator + (BOOL) isValidZipcode:(NSString*)value { const char *cvalue = [value UTF8String]; int len = strlen(cvalue); if (len != 6) { return FALSE; } for (int i = 0; i < len; i++) { if (!(cvalue[i] >= '0' && cvalue[i] <= '9')) { return FALSE; } } return TRUE; } + (BOOL) validateEmail:(NSString *)candidate { NSArray *array = [candidate componentsSeparatedByString:@"."]; if ([array count] >= 4) { return FALSE; } NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex]; return [emailTest evaluateWithObject:candidate]; } + (BOOL) isValidEmail:(NSString*)value { static int state[5][3] = { {1, -1, -1}, {1, 2, -1}, {3, -1, -1}, {3, -1, 4}, {4, -1, -1} }; BOOL valid = TRUE; const char *cvalue = [value UTF8String]; int currentState = 0; int len = strlen(cvalue); int index; for (int i = 0; i < len && valid; i++) { index = getIndex(cvalue[i]); if (index < 0) { valid = FALSE; } else { currentState = state[currentState][index]; if (currentState < 0) { valid = FALSE; } } } //end state is invalid if (currentState != 4) { valid = FALSE; } return valid; } + (BOOL) isValidNumber:(NSString*)value{ const char *cvalue = [value UTF8String]; int len = strlen(cvalue); for (int i = 0; i < len; i++) { if(!isNumber(cvalue[i])){ return FALSE; } } return TRUE; } + (BOOL) isValidPhone:(NSString*)value { const char *cvalue = [value UTF8String]; int len = strlen(cvalue); if (len != 11) { return FALSE; } if (![IdentifierValidator isValidNumber:value]) { return FALSE; } NSString *preString = [[NSString stringWithFormat:@"%@",value] substringToIndex:2]; if ([preString isEqualToString:@"13"] || [preString isEqualToString: @"15"] || [preString isEqualToString: @"18"]) { return TRUE; } else { return FALSE; } return TRUE; } + (BOOL) isValidString:(NSString*)value { return value && [value length]; } const int factor[] = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };//加权因子 const int checktable[] = { 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 };//校验值对应表 + (BOOL) isValidIdentifier:(NSString*)value { const int LENGTH = 18; const char *str = [[value lowercaseString] UTF8String]; NSInteger i; NSInteger length = strlen(str); BOOL result = TRUE; /* * identifier length is invalid */ if (15 != length && LENGTH != length) { result = FALSE; } else { for (i = 1; i < length - 1; i++) { if(!(str[i] >= '0' && str[i] <= '9')) { result = FALSE; break; } } if (result) { if(LENGTH == length) { if (!((str[i] >= '0' && str[i] <= '9')||str[i] == 'X'||str[i] == 'x')) { result = FALSE; } } } /* * check sum for second generation identifier */ if (result && length == LENGTH) { int i; int *ids = malloc(sizeof(int)*LENGTH); for (i = 0; i < LENGTH; i++) { ids[i] = str[i] - 48; } int checksum = 0; for (i = 0; i < LENGTH - 1; i ++ ) { checksum += ids[i] * factor[i]; } if (ids[17] == checktable[checksum%11]|| (str[17] == 'x' && checktable[checksum % 11] == 10)) { result = TRUE; } else { result = FALSE; } free(ids); ids = NULL; } } return result; } + (BOOL) isValidPassport:(NSString*)value { const char *str = [value UTF8String]; char first = str[0]; NSInteger length = strlen(str); if (!(first == 'P' || first == 'G')) { return FALSE; } if (first == 'P') { if (length != 8) { return FALSE; } } if (first == 'G') { if (length != 9) { return FALSE; } } BOOL result = TRUE; for (NSInteger i = 1; i < length; i++) { if (!(str[i] >= '0' && str[i] <= '9')) { result = FALSE; break; } } return result; } /* * 常用信用卡卡号规则 * Issuer Identifier Card Number Length * Diner's Club 300xxx-305xxx, 3095xx, 36xxxx, 38xxxx 14 * American Express 34xxxx, 37xxxx 15 * VISA 4xxxxx 13, 16 * MasterCard 51xxxx-55xxxx 16 * JCB 3528xx-358xxx 16 * Discover 6011xx 16 * 银联 622126-622925 16 * * 信用卡号验证基本算法: * 偶数位卡号奇数位上数字*2,奇数位卡号偶数位上数字*2。 * 大于10的位数减9。 * 全部数字加起来。 * 结果不是10的倍数的卡号非法。 * prefrences link:http://www.truevue.org/licai/credit-card-no * */ + (BOOL) isValidCreditNumber:(NSString*)value { BOOL result = TRUE; NSInteger length = [value length]; if (length >= 13) { result = [IdentifierValidator isValidNumber:value]; if (result) { NSInteger twoDigitBeginValue = [[value substringWithRange:NSMakeRange(0, 2)] integerValue]; NSInteger threeDigitBeginValue = [[value substringWithRange:NSMakeRange(0, 3)] integerValue]; NSInteger fourDigitBeginValue = [[value substringWithRange:NSMakeRange(0, 4)] integerValue]; //Diner's Club if (((threeDigitBeginValue >= 300 && threeDigitBeginValue <= 305)|| fourDigitBeginValue == 3095||twoDigitBeginValue==36||twoDigitBeginValue==38) && (14 != length)) { result = FALSE; } //VISA else if([value isStartWithString:@"4"] && !(13 == length||16 == length)) { result = FALSE; } //MasterCard else if((twoDigitBeginValue >= 51||twoDigitBeginValue <= 55) && (16 != length)) { result = FALSE; } //American Express else if(([value isStartWithString:@"34"]||[value isStartWithString:@"37"]) && (15 != length)) { result = FALSE; } //Discover else if([value isStartWithString:@"6011"] && (16 != length)) { result = FALSE; } else { NSInteger begin = [[value substringWithRange:NSMakeRange(0, 6)] integerValue]; //CUP if ((begin >= 622126 && begin <= 622925) && (16 != length)) { result = FALSE; } //other else { result = TRUE; } } } if (result) { NSInteger digitValue; NSInteger checkSum = 0; NSInteger index = 0; NSInteger leftIndex; //even length, odd index if (0 == length%2) { index = 0; leftIndex = 1; } //odd length, even index else { index = 1; leftIndex = 0; } while (index < length) { digitValue = [[value substringWithRange:NSMakeRange(index, 1)] integerValue]; digitValue = digitValue*2; if (digitValue >= 10) { checkSum += digitValue/10 + digitValue%10; } else { checkSum += digitValue; } digitValue = [[value substringWithRange:NSMakeRange(leftIndex, 1)] integerValue]; checkSum += digitValue; index += 2; leftIndex += 2; } result = (0 == checkSum%10) ? TRUE:FALSE; } } else { result = FALSE; } return result; } + (BOOL) isValidBirthday:(NSString*)birthday { BOOL result = FALSE; if (birthday && 8 == [birthday length]) { NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyyMMdd"]; NSDate *date = [formatter dateFromString:birthday]; [formatter release]; if (date) { result = TRUE; } } return result; } + (BOOL) isChinaUnicomPhoneNumber:(NSString*) phonenumber { /** * 手机号码 * 移动:134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188 * 联通:130,131,132,152,155,156,185,186 * 电信:133,1349,153,180,189 */ // NSString * MOBILE = @"^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$"; /** 10 * 中国移动:China Mobile 11 * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188 12 */ // NSString * CM = @"^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$"; // /** // 15 * 中国联通:China Unicom // 16 * 130,131,132,152,155,156,185,186 // 17 */ NSString * CU = @"^1(3[0-2]|5[256]|8[56])\\d{8}$"; // /** // 20 * 中国电信:China Telecom // 21 * 133,1349,153,180,189 // 22 */ // NSString * CT = @"^1((33|53|8[09])[0-9]|349)\\d{7}$"; // /** // 25 * 大陆地区固话及小灵通 // 26 * 区号:010,020,021,022,023,024,025,027,028,029 // 27 * 号码:七位或八位 // 28 */ // NSString * PHS = @"^0(10|2[0-5789]|\\d{3})\\d{7,8}$"; // NSString * PHS1 = @"^0(10|2[0-5789]|\\d{3}-)\\d{7,8}$"; // NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE]; // NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM]; NSPredicate *regextestcu = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU]; // NSPredicate *regextestct = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT]; // NSPredicate *regextestphs = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", PHS]; // NSPredicate *regextestphs1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", PHS1]; if (//([regextestmobile evaluateWithObject:phonenumber] == YES)|| // ([regextestcm evaluateWithObject:phonenumber] == YES)|| // ([regextestct evaluateWithObject:phonenumber] == YES)|| ([regextestcu evaluateWithObject:phonenumber] == YES) // || ([regextestphs evaluateWithObject:phonenumber] == YES) // || ([regextestphs1 evaluateWithObject:phonenumber] == YES) ) { return YES; } else { return NO; } } + (BOOL) isValid:(IdentifierType) type value:(NSString*) value { if (!value ||[[value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] isEqualToString:@""]) { return FALSE; } BOOL result = TRUE; switch (type) { case IdentifierTypeZipCode: result = [IdentifierValidator isValidZipcode:value]; break; case IdentifierTypeEmail: // result = [IdentifierValidator isValidEmail:value]; result = [IdentifierValidator validateEmail:value]; break; case IdentifierTypePhone: result = [IdentifierValidator isValidPhone:value]; break; case IdentifierTypeUnicomPhone: result = [IdentifierValidator isChinaUnicomPhoneNumber:value]; break; case IdentifierTypeQQ: result = [IdentifierValidator isValidNumber:value]; break; case IdentifierTypeNumber: result = [IdentifierValidator isValidNumber:value]; break; case IdentifierTypeString: result = [IdentifierValidator isValidString:value]; break; case IdentifierTypeIdentifier: result = [IdentifierValidator isValidIdentifier:value]; break; case IdentifierTypePassort: result = [IdentifierValidator isValidPassport:value]; break; case IdentifierTypeCreditNumber: result = [IdentifierValidator isValidCreditNumber:value]; break; case IdentifierTypeBirthday: result = [IdentifierValidator isValidBirthday:value]; break; default: break; } return result; } - (void) dealloc { [super dealloc]; } @end