身份证号码正则验证

源代码来自DevStore,我加以整理以备用。

在 MyEclipse 中新建 Application Client Project, IDCardValidate.

IDCard.java

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

Main.java

 1 /** 
 2 //* @param args 
 3 //* @throws ParseException 
 4 //*/ 
 5 public class Main {
 6     public static void main(String[] args) {
 7         // TODO Auto-generated method stub
 8         String IDCardNum = "350111681128058"; 
 9         IDCard id = new IDCard();
10         System.out.println("开始验证..."); 
11         System.out.println(id.IDCardValidate(IDCardNum.toUpperCase())); 
12         //System.out.println(cc.isDate("1996-02-29")); 
13     }
14 
15 }

 

posted @ 2015-05-18 17:46  壬子木  阅读(299)  评论(0)    收藏  举报