Posted on 2008-09-01 17:41
RichardHe 阅读(5246)
评论(11) 编辑 收藏 引用
C++身份证号验证
由于项目需要,在网上的例子大多数都是C#的,所以添加了这个身份证号的验证的C++程序,想用正则表达式,但又不会,有哪个会的可以指点下,小弟我不胜感激啊!
可能有的地方写的不好,欢迎指点:
.H文件
1
#ifndef _CCHECKIDCARD_
2
#define _CCHECKIDCARD_
3
#include <string>
4
using namespace std;
5![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
6
class cCheckIdCard
7![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
8
public:
9
cCheckIdCard(void);
10
//身份证验证
11
bool CheckIDCard(const string& Id);
12
13
//18位身份证验证
14
bool CheckIDCard18(const string& Id);
15![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
16
//15位身份证验证
17
bool CheckIDCard15(const string& Id);
18![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
19
//生日验证
20
bool CheckDate(const string& Year, const string& const Month, const string& Day);
21
22
//最后一位校验
23
bool cCheckIdCard::VarifyCode(const string& Id);
24
25
//实现身份证的15位转18位
26
string per15To18(const string& Id);
27![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
28
//获得生日
29
string getBirthday(const string& Id);
30![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
31
virtual ~cCheckIdCard(void);
32![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
33
};
34
#endif//_CCHECKIDCARD_
CPP文件:
1
#include "cCheckIdCard.h"
2![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
3
cCheckIdCard::cCheckIdCard(void)
4![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
5
}
6![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
7
cCheckIdCard::~cCheckIdCard(void)
8![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
9
}
10![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//// <summary>
11
/// 验证身份证号码
12
/// </summary>
13
/// <param name="Id">身份证号码</param>
14
/// <returns>验证成功为True,否则为False</returns> 15
bool cCheckIdCard::CheckIDCard(const string& Id)
16![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
17
if (Id.length() == 18)
18![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
19
bool check = CheckIDCard18(Id);
20
return check;
21
}
22
else if (Id.length() == 15)
23![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
24
bool check = CheckIDCard15(Id);
25
return check;
26
}
27
else
28![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
29
return false;
30
}
31
}
32![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
33
bool cCheckIdCard::CheckIDCard18(const string& Id)
34![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
35![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
string address[] =
{"11","22","35","44","53","12","23","36","45","54","13","31","37","46","61","14","32","41","50","62","15","33","42","51","63","21","34","43","52","64","65","71","81","82","91"};
36
for( int i = 0; i<= 34; i++)
37![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
38
if (!(Id.substr(0,2) != address[i]))
39
break;//省份验证正确
40
else if (i == 34)
41
return false;//省份验证错误
42
}
43![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
44
string birth = Id.substr(6, 8);
45
if(!CheckDate(birth.substr(0,4), birth.substr(4,2), birth.substr(6,2)))
46
return false;//生日验证错误
47![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
48
if(!VarifyCode(Id))
49
return false;//最后一位校验错误
50
return true;
51
}
52![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
53
bool cCheckIdCard::CheckIDCard15(const string& Id)
54![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
55
string newID = per15To18(Id);
56![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
57
if(!CheckIDCard18(newID))
58
return false;
59
return true;
60
}
61![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
62
string cCheckIdCard::getBirthday(const string& Id)
63![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
64
if(!CheckIDCard(Id))
65
return "";//生日验证错误
66
else
67![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
68
string birth;
69
if (Id.length() == 15)
70![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
71
string newID = per15To18(Id);
72
birth = newID.substr(6, 8);
73
return birth.insert(6,"-").insert(4,"-");
74
}
75
else
76
return Id.substr(6,8).insert(6,"-").insert(4,"-");
77
}
78
}
79![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
80
bool cCheckIdCard::CheckDate(const string& Year, const string& Month, const string& Day)
81![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
82
int iYear = atoi(Year.c_str());
83
int iMonth = atoi(Month.c_str());
84
int iDay = atoi(Day.c_str());
85![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
int Days[12]=
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
86
if(iMonth<1 || iMonth>12) return false;
87![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
88
bool b_IsLeapYear=false;
89
if(iYear%4==0)
90![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
91
b_IsLeapYear=true;
92![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
93
if(!(iYear%100==0 && iYear%400==0)) b_IsLeapYear=false;
94
}
95![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
96
if(b_IsLeapYear) Days[1]=29;
97
else Days[1]=28;
98![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
99
if(iDay<0 || iDay>Days[iMonth-1]) return false;
100![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
101
return true;
102
}
103![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
104
bool cCheckIdCard::VarifyCode( const string& Id)
105![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
106
char perIDSrc[19];
107
strcpy(perIDSrc,Id.c_str());
108
int iS = 0;
109![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
int const iW[]=
{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
110
char const LastCode[]="10X98765432";
111![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
112
for(int i=0;i<17;i++)
113![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
114
iS += (int)(perIDSrc[i]-'0') * iW[i];
115
}
116![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
117
int iY = iS%11;
118
char ch = LastCode[iY];
119
string lastChar;
120
lastChar.insert(lastChar.begin(), ch );
121
122
if(lastChar != Id.substr(17,1))
123
return false;
124
return true;
125
}
126![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
127
//实现身份证的15位转18位
128
string cCheckIdCard::per15To18(const string& Id)
129![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
130
if(Id.length() != 15)
131
return "";
132
char perIDSrc[19];
133
strcpy(perIDSrc,Id.c_str());
134
int iS = 0;
135![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
136
//加权因子常数
137![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
int const iW[]=
{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
138
//校验码常数
139
char const LastCode[]="10X98765432";
140
//新身份证号
141
char perIDNew[19];
142![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
143
for( int i = 0; i < 6; i++ )
144![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
145
perIDNew[i] = perIDSrc[i];
146
}
147![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
148
//填在第6位及第7位上填上‘1’,‘9’两个数字
149
perIDNew[6] = '1';
150
perIDNew[7] = '9';
151![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
152
for( int i = 8; i < 17; i++ )
153![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
154
perIDNew[i] = perIDSrc[i - 2];
155
}
156![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
157
//进行加权求和
158
for( int i=0; i<17; i++)
159![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
160
iS += (perIDNew[i]-'0') * iW[i];
161![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//**//**//*
162
对于perIDNew[i]-'0'解释一下:
163
perIDNew[i]->ASCII码,取得它的值实际是十进制数;
164
'0' ->ASCII码,同上;
165
perIDNew[i]-'0' -> 得到具体的十进制数值;
166
对于这里面的为什么会进行转换,具体去看C++PRIMER,呵呵。
167
*/
168
}
169
170
//取模运算,得到模值
171
int iY = iS%11;
172
//从LastCode中取得以模为索引号的值,加到身份证的最后一位,即为新身份证号。
173
perIDNew[17] = LastCode[iY];
174
//加上结束符
175
perIDNew[18] = '\0';
176![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
177
string tempstr = perIDNew;
178
return tempstr;
179
}
测试:
#include "stdafx.h"
#include "cCheckIdCard.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
cCheckIdCard tempID;
bool b = tempID.CheckIDCard("");//身份证号
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
string birthday = tempID.getBirthday("12345678901234567");//12345678901234567表示你要验证的身份证号
cout << birthday << endl;
return 0;
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)