代码语言:javascript复制
#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]||
(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;
}
else
{
checkSum = digitValue;
}
digitValue = [[value substringWithRange:NSMakeRange(leftIndex, 1)] integerValue];
checkSum = digitValue;
index = 2;
leftIndex = 2;
}
result = (0 == checkSum) ? 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</pre>