Posted on 2008-09-01 17:41
RichardHe 阅读(5292)
评论(11) 编辑 收藏 引用
C++身份证号验证
由于项目需要,在网上的例子大多数都是C#的,所以添加了这个身份证号的验证的C++程序,想用正则表达式,但又不会,有哪个会的可以指点下,小弟我不胜感激啊!
可能有的地方写的不好,欢迎指点:
.H文件
1#ifndef _CCHECKIDCARD_
2#define _CCHECKIDCARD_
3#include <string>
4using namespace std;
5
6class cCheckIdCard
7{
8public:
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
3cCheckIdCard::cCheckIdCard(void)
4{
5}
6
7cCheckIdCard::~cCheckIdCard(void)
8{
9}
10/**//// <summary>
11/// 验证身份证号码
12/// </summary>
13/// <param name="Id">身份证号码</param>
14/// <returns>验证成功为True,否则为False</returns> 15bool 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
33bool 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
53bool cCheckIdCard::CheckIDCard15(const string& Id)
54{
55 string newID = per15To18(Id);
56
57 if(!CheckIDCard18(newID))
58 return false;
59 return true;
60}
61
62string 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
80bool 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
104bool 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位
128string 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;
}