#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) isChinaUnicomPhoneNumber:(NSString*) phoneNumber
//{
// BOOL unicom = TRUE;
// NSString *mobileNumFormat13 = @"[1]{1}[3]{1}[4-9]{1}[0-9]{8}";
// NSString *mobileNumFormat14 = @"[1]{1}[4]{1}[7]{1}[0-9]{8}";
// NSString *mobileNumFormat15 = @"[1]{1}[5]{1}[012789]{1}[0-9]{8}";
// NSString *mobileNumFormat18 = @"[1]{1}[8]{1}[2378]{1}[0-9]{8}";
// NSPredicate *predicate13 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",mobileNumFormat13];
// NSPredicate *predicate14 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",mobileNumFormat14];
// NSPredicate *predicate15 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",mobileNumFormat15];
// NSPredicate *predicate18 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",mobileNumFormat18];
// if ([predicate13 evaluateWithObject:phoneNumber] ||
// [predicate14 evaluateWithObject:phoneNumber] ||
// [predicate15 evaluateWithObject:phoneNumber] ||
// [predicate18 evaluateWithObject:phoneNumber])
// {
// unicom = FALSE;
// }
// return unicom;
//}
+ (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
相关推荐
在iOS开发中,有时我们需要根据用户输入的银行卡号来获取相关的银行信息,如发行行、卡名和卡种。这通常涉及到银行卡号的解析和验证,以及与已知的银行卡数据库进行匹配。以下是对这个话题的详细阐述: 1. **银行卡...
银行卡号通常由发卡机构标识符(Bank Identification Number, BIN)组成,这是前几位数字,用于识别发卡银行或金融机构。BIN数据库是关键资源,它包含了全球各类银行卡的BIN信息,你可以通过购买或使用开源项目来...
"iOS手机银行卡号输入格式化"这个主题主要涉及到以下几个方面的知识点: 1. **文本字段(UITextField)的自定义格式化**:在iOS中,我们通常使用UITextField来接收用户的输入,特别是银行卡号这种较长的数字序列。...
在iOS开发中,有时我们需要根据用户的银行卡号来获取对应的银行名称和对应的银行logo图片,以提供更加人性化的用户体验。这个项目提供了一种解决方案,通过"ios银行卡号获取银行名称及图片",使得开发者能够轻松集成...
6. **解析银行卡号**:从识别出的文字中,使用正则表达式或其他方法提取出完整的银行卡号。 7. **显示结果**:将识别到的银行卡号展示给用户,并提供下一步操作的指引,如验证卡号或保存卡信息。 8. **错误处理**...
在iOS开发中,手机号码验证是一项基础且重要的功能,它能确保用户提供的手机号码符合特定格式,从而提高数据的准确性和安全性。本文将深入探讨如何使用正则表达式进行iOS中的手机号码验证。 首先,我们需要了解手机...
在iOS开发中,为了提升用户体验,我们经常需要对用户输入的数据进行格式化处理,比如银行卡号和手机号的输入。在给定的标题“一句代码 实现银行卡手机号输入时格式化”中,我们可以理解到,有一种高效的方法可以实现...
在iOS开发中,实现类似支付宝“我的银行卡”列表的层叠效果是一项常见的需求,它可以为用户界面增添动态感和专业性。这个效果主要是通过动画来模拟银行卡在视觉上的堆叠和展开,使得用户在查看或管理多张银行卡时,...
这个"ios-匹配银行卡各个银行.zip"压缩包很可能包含了一套完整的解决方案,用于验证和识别用户输入的银行卡号所属的银行。下面将详细阐述相关知识点。 首先,我们来了解银行卡号的结构。银行卡号通常由16到22位数字...
1、功能:扫描银行卡识别信息( 银行名称、 银行卡号)并截取银行卡图像 2、应用场景:快速填充银行卡号的场景,比如商户进件、实名认证 3、原理: 3.1、自定义相机并利用第三方库SDK `libexbankcardios.a` 、`...
【作品名称】:基于OpenCV和TesseractOCRiOS的银行卡号识别 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】: 基于...
在iOS开发中,身份证和银行卡扫描是一项常见的需求,主要用于实名认证、支付验证等场景。本文将详细讨论如何实现这一功能,重点在于OCR(Optical Character Recognition,光学字符识别)技术的应用。 首先,我们...
在iOS开发中,为了提供良好的用户体验,经常需要对各种元素进行定制化设计,尤其是在金融类应用中,展示不同类型的银行卡并赋予相应的背景色是常见的需求。这个“ios-主要的银行卡类型 显示 背景色.zip”文件似乎...
总的来说,通过自定义UICollectionViewFlowLayout、创建自定义UICollectionViewCell、实现数据源和代理方法,以及添加交互细节,我们可以轻松地在iOS应用中实现“银行卡重叠卡片列表”的效果。这不仅展示了iOS开发中...
在iOS开发中,为了提升用户体验,特别是在涉及到敏感信息如银行卡号输入时,通常会采用特定的格式化方式来展示这些数据。"IOS 银行卡格式化(4个数字加一个空格)"这个主题主要关注如何在iOS应用中实现银行卡号的格式...
在iOS开发中,有时我们需要实现一个功能,即根据用户输入的银行卡号来判断该卡所属的银行。这个功能在很多应用场景下都非常实用,比如在线支付、金融应用等。本文将介绍如何通过银行卡号来获取银行名称,代码简洁...
8. **安全与隐私**:由于涉及用户的敏感信息,如银行卡号,必须遵循严格的安全规范,如不显示完整卡号,使用遮罩处理,以及在传输和存储数据时进行加密。 通过分析这个描述和标签,我们可以推测这个zip文件包含的...
"银行卡扫描SDK for IOS"是专为iOS平台设计的解决方案,允许用户通过手机摄像头快速、准确地读取银行卡上的信息,尤其是银行卡号。这个SDK的核心功能在于它的光学字符识别(OCR)技术,能够自动识别并提取卡片上的...
总的来说,"手机号/银行卡号插入空格格式"是一种实用的数据表示方法,它结合了可读性与安全性的考量。在实际的软件开发和数据处理中,我们需要充分理解并正确实现这种格式,同时确保数据的安全存储和传输,以保障...
在IT行业中,银行卡号码扫描是一项常见且实用的技术应用,它主要通过手机摄像头捕获银行卡上的磁条或芯片信息,从而自动识别银行卡号。这个过程通常依赖于特定的软件库和算法,例如提到的"card.io"开源项目。下面将...