1
.
/**
********************************* 身份证验证开始 ***************************************
*/
2
.
/**
3. * 身份证号码验证
4. * 1、号码的结构
5. * 公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,
6. * 八位数字出生日期码,三位数字顺序码和一位数字校验码。
7. * 2、地址码(前六位数)
8. * 表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。
9. * 3、出生日期码(第七位至十四位)
10. * 表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。
11. * 4、顺序码(第十五位至十七位)
12. * 表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,
13. * 顺序码的奇数分配给男性,偶数分配给女性。
14. * 5、校验码(第十八位数)
15. * (1)十七位数字本体码加权求和公式 S = Sum(Ai * Wi), i = 0,
, 16 ,先对前17位数字的权求和
16. * Ai:表示第i位置上的身份证号码数字值 Wi:表示第i位置上的加权因子 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4
17. * 2 (2)计算模 Y = mod(S, 11) (3)通过模得到对应的校验码 Y: 0 1 2 3 4 5 6 7 8 9 10 校验码: 1 0
18. * X 9 8 7 6 5 4 3 2
19.
*/
20
.
21
.
/**
22. * 功能:身份证的有效验证
23. *
@param
IDStr 身份证号
24. *
@return
有效:返回"" 无效:返回String信息
25. *
@throws
ParseException
26.
*/
27
. @SuppressWarnings(
"
unchecked
"
)
28
.
public
static
String IDCardValidate(String IDStr)
throws
ParseException {
29
. String errorInfo
=
""
;
//
记录错误信息
30
. String[] ValCodeArr
=
{
"
1
"
,
"
0
"
,
"
x
"
,
"
9
"
,
"
8
"
,
"
7
"
,
"
6
"
,
"
5
"
,
"
4
"
,
31
.
"
3
"
,
"
2
"
};
32
. String[] Wi
=
{
"
7
"
,
"
9
"
,
"
10
"
,
"
5
"
,
"
8
"
,
"
4
"
,
"
2
"
,
"
1
"
,
"
6
"
,
"
3
"
,
"
7
"
,
33
.
"
9
"
,
"
10
"
,
"
5
"
,
"
8
"
,
"
4
"
,
"
2
"
};
34
. String Ai
=
""
;
35
.
//
================ 号码的长度 15位或18位 ================
36
.
if
(IDStr.length()
!=
15
&&
IDStr.length()
!=
18
) {
37
. errorInfo
=
"
身份证号码长度应该为15位或18位。
"
;
38
.
return
errorInfo;
39
. }
40
.
//
=======================(end)========================
41
.
42
.
//
================ 数字 除最后以为都为数字 ================
43
.
if
(IDStr.length()
==
18
) {
44
. Ai
=
IDStr.substring(
0
,
17
);
45
. }
else
if
(IDStr.length()
==
15
) {
46
. Ai
=
IDStr.substring(
0
,
6
)
+
"
19
"
+
IDStr.substring(
6
,
15
);
47
. }
48
.
if
(isNumeric(Ai)
==
false
) {
49
. errorInfo
=
"
身份证15位号码都应为数字 ; 18位号码除最后一位外,都应为数字。
"
;
50
.
return
errorInfo;
51
. }
52
.
//
=======================(end)========================
53
.
54
.
//
================ 出生年月是否有效 ================
55
. String strYear
=
Ai.substring(
6
,
10
);
//
年份
56
. String strMonth
=
Ai.substring(
10
,
12
);
//
月份
57
. String strDay
=
Ai.substring(
12
,
14
);
//
月份
58
.
if
(isDate(strYear
+
"
-
"
+
strMonth
+
"
-
"
+
strDay)
==
false
) {
59
. errorInfo
=
"
身份证生日无效。
"
;
60
.
return
errorInfo;
61
. }
62
. GregorianCalendar gc
=
new
GregorianCalendar();
63
. SimpleDateFormat s
=
new
SimpleDateFormat(
"
yyyy-MM-dd
"
);
64
.
if
((gc.get(Calendar.YEAR)
-
Integer.parseInt(strYear))
>
150
65
.
||
(gc.getTime().getTime()
-
s.parse(
66
. strYear
+
"
-
"
+
strMonth
+
"
-
"
+
strDay).getTime())
<
0
) {
67
. errorInfo
=
"
身份证生日不在有效范围。
"
;
68
.
return
errorInfo;
69
. }
70
.
if
(Integer.parseInt(strMonth)
>
12
||
Integer.parseInt(strMonth)
==
0
) {
71
. errorInfo
=
"
身份证月份无效
"
;
72
.
return
errorInfo;
73
. }
74
.
if
(Integer.parseInt(strDay)
>
31
||
Integer.parseInt(strDay)
==
0
) {
75
. errorInfo
=
"
身份证日期无效
"
;
76
.
return
errorInfo;
77
. }
78
.
//
=====================(end)=====================
79
.
80
.
//
================ 地区码时候有效 ================
81
. Hashtable h
=
GetAreaCode();
82
.
if
(h.get(Ai.substring(
0
,
2
))
==
null
) {
83
. errorInfo
=
"
身份证地区编码错误。
"
;
84
.
return
errorInfo;
85
. }
86
.
//
==============================================
87
.
88
.
//
================ 判断最后一位的值 ================
89
.
int
TotalmulAiWi
=
0
;
90
.
for
(
int
i
=
0
; i
<
17
; i
++
) {
91
. TotalmulAiWi
=
TotalmulAiWi
92
.
+
Integer.parseInt(String.valueOf(Ai.charAt(i)))
93
.
*
Integer.parseInt(Wi[i]);
94
. }
95
.
int
modValue
=
TotalmulAiWi
%
11
;
96
. String strVerifyCode
=
ValCodeArr[modValue];
97
. Ai
=
Ai
+
strVerifyCode;
98
.
99
.
if
(IDStr.length()
==
18
) {
100
.
if
(Ai.equals(IDStr)
==
false
) {
101
. errorInfo
=
"
身份证无效,不是合法的身份证号码
"
;
102
.
return
errorInfo;
103
. }
104
. }
else
{
105
.
return
""
;
106
. }
107
.
//
=====================(end)=====================
108
.
return
""
;
109
. }
110
.
111
.
/**
112. * 功能:设置地区编码
113. *
@return
Hashtable 对象
114.
*/
115
. @SuppressWarnings(
"
unchecked
"
)
116
.
private
static
Hashtable GetAreaCode() {
117
. Hashtable hashtable
=
new
Hashtable();
118
. hashtable.put(
"
11
"
,
"
北京
"
);
119
. hashtable.put(
"
12
"
,
"
天津
"
);
120
. hashtable.put(
"
13
"
,
"
河北
"
);
121
. hashtable.put(
"
14
"
,
"
山西
"
);
122
. hashtable.put(
"
15
"
,
"
内蒙古
"
);
123
. hashtable.put(
"
21
"
,
"
辽宁
"
);
124
. hashtable.put(
"
22
"
,
"
吉林
"
);
125
. hashtable.put(
"
23
"
,
"
黑龙江
"
);
126
. hashtable.put(
"
31
"
,
"
上海
"
);
127
. hashtable.put(
"
32
"
,
"
江苏
"
);
128
. hashtable.put(
"
33
"
,
"
浙江
"
);
129
. hashtable.put(
"
34
"
,
"
安徽
"
);
130
. hashtable.put(
"
35
"
,
"
福建
"
);
131
. hashtable.put(
"
36
"
,
"
江西
"
);
132
. hashtable.put(
"
37
"
,
"
山东
"
);
133
. hashtable.put(
"
41
"
,
"
河南
"
);
134
. hashtable.put(
"
42
"
,
"
湖北
"
);
135
. hashtable.put(
"
43
"
,
"
湖南
"
);
136
. hashtable.put(
"
44
"
,
"
广东
"
);
137
. hashtable.put(
"
45
"
,
"
广西
"
);
138
. hashtable.put(
"
46
"
,
"
海南
"
);
139
. hashtable.put(
"
50
"
,
"
重庆
"
);
140
. hashtable.put(
"
51
"
,
"
四川
"
);
141
. hashtable.put(
"
52
"
,
"
贵州
"
);
142
. hashtable.put(
"
53
"
,
"
云南
"
);
143
. hashtable.put(
"
54
"
,
"
西藏
"
);
144
. hashtable.put(
"
61
"
,
"
陕西
"
);
145
. hashtable.put(
"
62
"
,
"
甘肃
"
);
146
. hashtable.put(
"
63
"
,
"
青海
"
);
147
. hashtable.put(
"
64
"
,
"
宁夏
"
);
148
. hashtable.put(
"
65
"
,
"
新疆
"
);
149
. hashtable.put(
"
71
"
,
"
台湾
"
);
150
. hashtable.put(
"
81
"
,
"
香港
"
);
151
. hashtable.put(
"
82
"
,
"
澳门
"
);
152
. hashtable.put(
"
91
"
,
"
国外
"
);
153
.
return
hashtable;
154
. }
155
.
156
.
/**
157. * 功能:判断字符串是否为数字
158. *
@param
str
159. *
@return
160.
*/
161
.
private
static
boolean
isNumeric(String str) {
162
. Pattern pattern
=
Pattern.compile(
"
[0-9]*
"
);
163
. Matcher isNum
=
pattern.matcher(str);
164
.
if
(isNum.matches()) {
165
.
return
true
;
166
. }
else
{
167
.
return
false
;
168
. }
169
. }
170
.
171
.
/**
172. * 功能:判断字符串是否为日期格式
173. *
@param
str
174. *
@return
175.
*/
176
.
public
static
boolean
isDate(String strDate) {
177
. Pattern pattern
=
Pattern
178
. .compile(
"
^((//d{2}(([02468][048])|([13579][26]))[//-/////s]?((((0?[13578])|(1[02]))[//-/////s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[//-/////s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[//-/////s]?((0?[1-9])|([1-2][0-9])))))|(//d{2}(([02468][1235679])|([13579][01345789]))[//-/////s]?((((0?[13578])|(1[02]))[//-/////s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[//-/////s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[//-/////s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(//s(((0?[0-9])|([1-2][0-3]))//:([0-5]?[0-9])((//s)|(//:([0-5]?[0-9])))))?$
"
);
179
. Matcher m
=
pattern.matcher(strDate);
180
.
if
(m.matches()) {
181
.
return
true
;
182
. }
else
{
183
.
return
false
;
184
. }
185
. }
186
.
187
.
/**
188. *
@param
args
189. *
@throws
ParseException
190.
*/
191
.
//
public static void main(String[] args) throws ParseException {
192
.
//
//
String IDCardNum="210102820826411";
193
.
//
//
String IDCardNum="210102198208264114";
194
.
//
String IDCardNum = "500113198606245216";
195
.
//
CommonUtil cc = new CommonUtil();
196
.
//
System.out.println(cc.IDCardValidate(IDCardNum));
197
.
//
//
System.out.println(cc.isDate("1996-02-29"));
198
.
//
}
199
.
/**
********************************* 身份证验证结束 ***************************************
*/