C++身份證號驗證
由于項目需要,在網上的例子大多數都是C#的,所以添加了這個身份證號的驗證的C++程序,想用正則表達式,但又不會,有哪個會的可以指點下,小弟我不勝感激??!
可能有的地方寫的不好,歡迎指點:
.H文件
CPP文件:
測試:
#include "stdafx.h"
#include "cCheckIdCard.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
cCheckIdCard tempID;
bool b = tempID.CheckIDCard("");//身份證號

string birthday = tempID.getBirthday("12345678901234567");//12345678901234567表示你要驗證的身份證號
cout << birthday << endl;
return 0;
}

由于項目需要,在網上的例子大多數都是C#的,所以添加了這個身份證號的驗證的C++程序,想用正則表達式,但又不會,有哪個會的可以指點下,小弟我不勝感激??!
可能有的地方寫的不好,歡迎指點:
.H文件
1
#ifndef _CCHECKIDCARD_
2
#define _CCHECKIDCARD_
3
#include <string>
4
using namespace std;
5
6
class cCheckIdCard
7
{
8
public:
9
cCheckIdCard(void);
10
//身份證驗證
11
bool CheckIDCard(const string& Id);
12
13
//18位身份證驗證
14
bool CheckIDCard18(const string& Id);
15
16
//15位身份證驗證
17
bool CheckIDCard15(const string& Id);
18
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
28
//獲得生日
29
string getBirthday(const string& Id);
30
31
virtual ~cCheckIdCard(void);
32
33
};
34
#endif//_CCHECKIDCARD_
#ifndef _CCHECKIDCARD_2
#define _CCHECKIDCARD_3
#include <string>4
using namespace std;5

6
class cCheckIdCard7
{8
public:9
cCheckIdCard(void);10
//身份證驗證11
bool CheckIDCard(const string& Id);12
13
//18位身份證驗證14
bool CheckIDCard18(const string& Id);15

16
//15位身份證驗證17
bool CheckIDCard15(const string& Id);18

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

28
//獲得生日29
string getBirthday(const string& Id);30

31
virtual ~cCheckIdCard(void);32

33
};34
#endif//_CCHECKIDCARD_CPP文件:
1
#include "cCheckIdCard.h"
2
3
cCheckIdCard::cCheckIdCard(void)
4
{
5
}
6
7
cCheckIdCard::~cCheckIdCard(void)
8
{
9
}
10
/// <summary>
11
/// 驗證身份證號碼
12
/// </summary>
13
/// <param name="Id">身份證號碼</param>
14
/// <returns>驗證成功為True,否則為False</returns>
15
bool cCheckIdCard::CheckIDCard(const string& Id)
16
{
17
if (Id.length() == 18)
18
{
19
bool check = CheckIDCard18(Id);
20
return check;
21
}
22
else if (Id.length() == 15)
23
{
24
bool check = CheckIDCard15(Id);
25
return check;
26
}
27
else
28
{
29
return false;
30
}
31
}
32
33
bool cCheckIdCard::CheckIDCard18(const string& Id)
34
{
35
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
{
38
if (!(Id.substr(0,2) != address[i]))
39
break;//省份驗證正確
40
else if (i == 34)
41
return false;//省份驗證錯誤
42
}
43
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
48
if(!VarifyCode(Id))
49
return false;//最后一位校驗錯誤
50
return true;
51
}
52
53
bool cCheckIdCard::CheckIDCard15(const string& Id)
54
{
55
string newID = per15To18(Id);
56
57
if(!CheckIDCard18(newID))
58
return false;
59
return true;
60
}
61
62
string cCheckIdCard::getBirthday(const string& Id)
63
{
64
if(!CheckIDCard(Id))
65
return "";//生日驗證錯誤
66
else
67
{
68
string birth;
69
if (Id.length() == 15)
70
{
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
80
bool cCheckIdCard::CheckDate(const string& Year, const string& Month, const string& Day)
81
{
82
int iYear = atoi(Year.c_str());
83
int iMonth = atoi(Month.c_str());
84
int iDay = atoi(Day.c_str());
85
int Days[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
86
if(iMonth<1 || iMonth>12) return false;
87
88
bool b_IsLeapYear=false;
89
if(iYear%4==0)
90
{
91
b_IsLeapYear=true;
92
93
if(!(iYear%100==0 && iYear%400==0)) b_IsLeapYear=false;
94
}
95
96
if(b_IsLeapYear) Days[1]=29;
97
else Days[1]=28;
98
99
if(iDay<0 || iDay>Days[iMonth-1]) return false;
100
101
return true;
102
}
103
104
bool cCheckIdCard::VarifyCode( const string& Id)
105
{
106
char perIDSrc[19];
107
strcpy(perIDSrc,Id.c_str());
108
int iS = 0;
109
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
112
for(int i=0;i<17;i++)
113
{
114
iS += (int)(perIDSrc[i]-'0') * iW[i];
115
}
116
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
127
//實現身份證的15位轉18位
128
string cCheckIdCard::per15To18(const string& Id)
129
{
130
if(Id.length() != 15)
131
return "";
132
char perIDSrc[19];
133
strcpy(perIDSrc,Id.c_str());
134
int iS = 0;
135
136
//加權因子常數
137
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
143
for( int i = 0; i < 6; i++ )
144
{
145
perIDNew[i] = perIDSrc[i];
146
}
147
148
//填在第6位及第7位上填上‘1’,‘9’兩個數字
149
perIDNew[6] = '1';
150
perIDNew[7] = '9';
151
152
for( int i = 8; i < 17; i++ )
153
{
154
perIDNew[i] = perIDSrc[i - 2];
155
}
156
157
//進行加權求和
158
for( int i=0; i<17; i++)
159
{
160
iS += (perIDNew[i]-'0') * iW[i];
161
/**//*
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
177
string tempstr = perIDNew;
178
return tempstr;
179
}
#include "cCheckIdCard.h"2

3
cCheckIdCard::cCheckIdCard(void)4
{5
}6

7
cCheckIdCard::~cCheckIdCard(void)8
{9
}10
/// <summary>11
/// 驗證身份證號碼12
/// </summary>13
/// <param name="Id">身份證號碼</param>14
/// <returns>驗證成功為True,否則為False</returns>15
bool cCheckIdCard::CheckIDCard(const string& Id)16
{17
if (Id.length() == 18)18
{19
bool check = CheckIDCard18(Id);20
return check;21
}22
else if (Id.length() == 15)23
{24
bool check = CheckIDCard15(Id);25
return check;26
}27
else28
{29
return false;30
}31
}32

33
bool cCheckIdCard::CheckIDCard18(const string& Id)34
{35
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
{38
if (!(Id.substr(0,2) != address[i]))39
break;//省份驗證正確40
else if (i == 34)41
return false;//省份驗證錯誤42
}43

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

48
if(!VarifyCode(Id))49
return false;//最后一位校驗錯誤50
return true;51
}52

53
bool cCheckIdCard::CheckIDCard15(const string& Id)54
{55
string newID = per15To18(Id);56

57
if(!CheckIDCard18(newID))58
return false;59
return true;60
}61

62
string cCheckIdCard::getBirthday(const string& Id)63
{64
if(!CheckIDCard(Id))65
return "";//生日驗證錯誤66
else67
{68
string birth;69
if (Id.length() == 15)70
{71
string newID = per15To18(Id);72
birth = newID.substr(6, 8);73
return birth.insert(6,"-").insert(4,"-");74
}75
else76
return Id.substr(6,8).insert(6,"-").insert(4,"-");77
}78
}79

80
bool cCheckIdCard::CheckDate(const string& Year, const string& Month, const string& Day)81
{82
int iYear = atoi(Year.c_str());83
int iMonth = atoi(Month.c_str());84
int iDay = atoi(Day.c_str());85
int Days[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};86
if(iMonth<1 || iMonth>12) return false; 87

88
bool b_IsLeapYear=false; 89
if(iYear%4==0) 90
{ 91
b_IsLeapYear=true; 92

93
if(!(iYear%100==0 && iYear%400==0)) b_IsLeapYear=false; 94
} 95

96
if(b_IsLeapYear) Days[1]=29; 97
else Days[1]=28; 98

99
if(iDay<0 || iDay>Days[iMonth-1]) return false; 100

101
return true; 102
} 103

104
bool cCheckIdCard::VarifyCode( const string& Id)105
{106
char perIDSrc[19];107
strcpy(perIDSrc,Id.c_str());108
int iS = 0;109
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

112
for(int i=0;i<17;i++)113
{114
iS += (int)(perIDSrc[i]-'0') * iW[i];115
}116

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

127
//實現身份證的15位轉18位128
string cCheckIdCard::per15To18(const string& Id)129
{130
if(Id.length() != 15)131
return "";132
char perIDSrc[19];133
strcpy(perIDSrc,Id.c_str());134
int iS = 0;135

136
//加權因子常數137
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

143
for( int i = 0; i < 6; i++ )144
{145
perIDNew[i] = perIDSrc[i];146
}147

148
//填在第6位及第7位上填上‘1’,‘9’兩個數字149
perIDNew[6] = '1';150
perIDNew[7] = '9';151

152
for( int i = 8; i < 17; i++ )153
{154
perIDNew[i] = perIDSrc[i - 2];155
}156

157
//進行加權求和158
for( int i=0; i<17; i++)159
{160
iS += (perIDNew[i]-'0') * iW[i];161
/**//*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

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[])
{
cCheckIdCard tempID;
bool b = tempID.CheckIDCard("");//身份證號
string birthday = tempID.getBirthday("12345678901234567");//12345678901234567表示你要驗證的身份證號
cout << birthday << endl;
return 0;
}


