Java的身份证号码工具类

来源:互联网 发布:淘宝美工关联 编辑:程序博客网 时间:2024/05/22 09:04

实现从15位~18位的身份证号码转换,校验中国大陆公民身份证、香港居民身份证、澳门身份证和台湾身份证。

代码片段(1)

017package my.tools;
018 
019import java.text.ParseException;
020import java.text.SimpleDateFormat;
021import java.util.Calendar;
022import java.util.Date;
023import java.util.HashMap;
024import java.util.Map;
025 
026import org.apache.commons.lang.StringUtils;
027 
028/**
029 * 身份证工具类
030 *
031 * @author June
032 * @version 1.0, 2010-06-17
033 */
034public classIdcardUtils extends StringUtils {
035 
036    /** 中国公民身份证号码最小长度。 */
037    publicstatic final int CHINA_ID_MIN_LENGTH = 15;
038 
039    /** 中国公民身份证号码最大长度。 */
040    publicstatic final int CHINA_ID_MAX_LENGTH = 18;
041 
042    /** 省、直辖市代码表 */
043    publicstatic final String cityCode[] = {
044            "11","12", "13","14", "15","21", "22","23", "31","32", "33","34", "35","36", "37","41",
045            "42","43", "44","45", "46","50", "51","52", "53","54", "61","62", "63","64", "65","71",
046            "81","82", "91"
047    };
048 
049    /** 每位加权因子 */
050    publicstatic final int power[] = {
051            7,9, 10,5, 8,4, 2,1, 6,3, 7,9, 10,5, 8,4, 2
052    };
053 
054    /** 第18位校检码 */
055    publicstatic final String verifyCode[] = {
056            "1","0", "X","9", "8","7", "6","5", "4","3", "2"
057    };
058    /** 最低年限 */
059    publicstatic final int MIN = 1930;
060    publicstatic Map<String, String> cityCodes =new HashMap<String, String>();
061    /** 台湾身份首字母对应数字 */
062    publicstatic Map<String, Integer> twFirstCode =new HashMap<String, Integer>();
063    /** 香港身份首字母对应数字 */
064    publicstatic Map<String, Integer> hkFirstCode =new HashMap<String, Integer>();
065    static{
066        cityCodes.put("11","北京");
067        cityCodes.put("12","天津");
068        cityCodes.put("13","河北");
069        cityCodes.put("14","山西");
070        cityCodes.put("15","内蒙古");
071        cityCodes.put("21","辽宁");
072        cityCodes.put("22","吉林");
073        cityCodes.put("23","黑龙江");
074        cityCodes.put("31","上海");
075        cityCodes.put("32","江苏");
076        cityCodes.put("33","浙江");
077        cityCodes.put("34","安徽");
078        cityCodes.put("35","福建");
079        cityCodes.put("36","江西");
080        cityCodes.put("37","山东");
081        cityCodes.put("41","河南");
082        cityCodes.put("42","湖北");
083        cityCodes.put("43","湖南");
084        cityCodes.put("44","广东");
085        cityCodes.put("45","广西");
086        cityCodes.put("46","海南");
087        cityCodes.put("50","重庆");
088        cityCodes.put("51","四川");
089        cityCodes.put("52","贵州");
090        cityCodes.put("53","云南");
091        cityCodes.put("54","西藏");
092        cityCodes.put("61","陕西");
093        cityCodes.put("62","甘肃");
094        cityCodes.put("63","青海");
095        cityCodes.put("64","宁夏");
096        cityCodes.put("65","新疆");
097        cityCodes.put("71","台湾");
098        cityCodes.put("81","香港");
099        cityCodes.put("82","澳门");
100        cityCodes.put("91","国外");
101        twFirstCode.put("A",10);
102        twFirstCode.put("B",11);
103        twFirstCode.put("C",12);
104        twFirstCode.put("D",13);
105        twFirstCode.put("E",14);
106        twFirstCode.put("F",15);
107        twFirstCode.put("G",16);
108        twFirstCode.put("H",17);
109        twFirstCode.put("J",18);
110        twFirstCode.put("K",19);
111        twFirstCode.put("L",20);
112        twFirstCode.put("M",21);
113        twFirstCode.put("N",22);
114        twFirstCode.put("P",23);
115        twFirstCode.put("Q",24);
116        twFirstCode.put("R",25);
117        twFirstCode.put("S",26);
118        twFirstCode.put("T",27);
119        twFirstCode.put("U",28);
120        twFirstCode.put("V",29);
121        twFirstCode.put("X",30);
122        twFirstCode.put("Y",31);
123        twFirstCode.put("W",32);
124        twFirstCode.put("Z",33);
125        twFirstCode.put("I",34);
126        twFirstCode.put("O",35);
127        hkFirstCode.put("A",1);
128        hkFirstCode.put("B",2);
129        hkFirstCode.put("C",3);
130        hkFirstCode.put("R",18);
131        hkFirstCode.put("U",21);
132        hkFirstCode.put("Z",26);
133        hkFirstCode.put("X",24);
134        hkFirstCode.put("W",23);
135        hkFirstCode.put("O",15);
136        hkFirstCode.put("N",14);
137    }
138 
139    /**
140     * 将15位身份证号码转换为18位
141     *
142     * @param idCard
143     *            15位身份编码
144     * @return 18位身份编码
145     */
146    publicstatic String conver15CardTo18(String idCard) {
147        String idCard18 ="";
148        if(idCard.length() != CHINA_ID_MIN_LENGTH) {
149            returnnull;
150        }
151        if(isNum(idCard)) {
152            // 获取出生年月日
153            String birthday = idCard.substring(6,12);
154            Date birthDate =null;
155            try{
156                birthDate =new SimpleDateFormat("yyMMdd").parse(birthday);
157            }catch (ParseException e) {
158                e.printStackTrace();
159            }
160            Calendar cal = Calendar.getInstance();
161            if(birthDate != null)
162                cal.setTime(birthDate);
163            // 获取出生年(完全表现形式,如:2010)
164            String sYear = String.valueOf(cal.get(Calendar.YEAR));
165            idCard18 = idCard.substring(0,6) + sYear + idCard.substring(8);
166            // 转换字符数组
167            char[] cArr = idCard18.toCharArray();
168            if(cArr != null) {
169                int[] iCard = converCharToInt(cArr);
170                intiSum17 = getPowerSum(iCard);
171                // 获取校验位
172                String sVal = getCheckCode18(iSum17);
173                if(sVal.length() > 0) {
174                    idCard18 += sVal;
175                }else {
176                    returnnull;
177                }
178            }
179        } else {
180            returnnull;
181        }
182        returnidCard18;
183    }
184 
185    /**
186     * 验证身份证是否合法
187     */
188    publicstatic boolean validateCard(String idCard) {
189        String card = idCard.trim();
190        if(validateIdCard18(card)) {
191            returntrue;
192        }
193        if(validateIdCard15(card)) {
194            returntrue;
195        }
196        String[] cardval = validateIdCard10(card);
197        if(cardval != null) {
198            if(cardval[2].equals("true")) {
199                returntrue;
200            }
201        }
202        returnfalse;
203    }
204 
205    /**
206     * 验证18位身份编码是否合法
207     *
208     * @param idCard 身份编码
209     * @return 是否合法
210     */
211    publicstatic boolean validateIdCard18(String idCard) {
212        booleanbTrue = false;
213        if(idCard.length() == CHINA_ID_MAX_LENGTH) {
214            // 前17位
215            String code17 = idCard.substring(0,17);
216            // 第18位
217            String code18 = idCard.substring(17, CHINA_ID_MAX_LENGTH);
218            if(isNum(code17)) {
219                char[] cArr = code17.toCharArray();
220                if(cArr != null) {
221                    int[] iCard = converCharToInt(cArr);
222                    intiSum17 = getPowerSum(iCard);
223                    // 获取校验位
224                    String val = getCheckCode18(iSum17);
225                    if(val.length() > 0) {
226                        if(val.equalsIgnoreCase(code18)) {
227                            bTrue =true;
228                        }
229                    }
230                }
231            }
232        }
233        returnbTrue;
234    }
235 
236    /**
237     * 验证15位身份编码是否合法
238     *
239     * @param idCard
240     *            身份编码
241     * @return 是否合法
242     */
243    publicstatic boolean validateIdCard15(String idCard) {
244        if(idCard.length() != CHINA_ID_MIN_LENGTH) {
245            returnfalse;
246        }
247        if(isNum(idCard)) {
248            String proCode = idCard.substring(0,2);
249            if(cityCodes.get(proCode) == null) {
250                returnfalse;
251            }
252            String birthCode = idCard.substring(6,12);
253            Date birthDate =null;
254            try{
255                birthDate =new SimpleDateFormat("yy").parse(birthCode.substring(0,2));
256            }catch (ParseException e) {
257                e.printStackTrace();
258            }
259            Calendar cal = Calendar.getInstance();
260            if(birthDate != null)
261                cal.setTime(birthDate);
262            if(!valiDate(cal.get(Calendar.YEAR), Integer.valueOf(birthCode.substring(2,4)),
263                    Integer.valueOf(birthCode.substring(4,6)))) {
264                returnfalse;
265            }
266        } else {
267            returnfalse;
268        }
269        returntrue;
270    }
271 
272    /**
273     * 验证10位身份编码是否合法
274     *
275     * @param idCard 身份编码
276     * @return 身份证信息数组
277     *         <p>
278     *         [0] - 台湾、澳门、香港 [1] - 性别(男M,女F,未知N) [2] - 是否合法(合法true,不合法false)
279     *         若不是身份证件号码则返回null
280     *         </p>
281     */
282    publicstatic String[] validateIdCard10(String idCard) {
283        String[] info =new String[3];
284        String card = idCard.replaceAll("[\\(|\\)]","");
285        if(card.length() != 8 && card.length() != 9 && idCard.length() !=10) {
286            returnnull;
287        }
288        if(idCard.matches("^[a-zA-Z][0-9]{9}$")) {// 台湾
289            info[0] ="台湾";
290            System.out.println("11111");
291            String char2 = idCard.substring(1,2);
292            if(char2.equals("1")) {
293                info[1] ="M";
294                System.out.println("MMMMMMM");
295            }else if (char2.equals("2")) {
296                info[1] ="F";
297                System.out.println("FFFFFFF");
298            }else {
299                info[1] ="N";
300                info[2] ="false";
301                System.out.println("NNNN");
302                returninfo;
303            }
304            info[2] = validateTWCard(idCard) ?"true" : "false";
305        } else if (idCard.matches("^[1|5|7][0-9]{6}\\(?[0-9A-Z]\\)?$")) {// 澳门
306            info[0] ="澳门";
307            info[1] ="N";
308            // TODO
309        } else if (idCard.matches("^[A-Z]{1,2}[0-9]{6}\\(?[0-9A]\\)?$")) {// 香港
310            info[0] ="香港";
311            info[1] ="N";
312            info[2] = validateHKCard(idCard) ?"true" : "false";
313        } else {
314            returnnull;
315        }
316        returninfo;
317    }
318 
319    /**
320     * 验证台湾身份证号码
321     *
322     * @param idCard
323     *            身份证号码
324     * @return 验证码是否符合
325     */
326    publicstatic boolean validateTWCard(String idCard) {
327        String start = idCard.substring(0,1);
328        String mid = idCard.substring(1,9);
329        String end = idCard.substring(9,10);
330        Integer iStart = twFirstCode.get(start);
331        Integer sum = iStart /10 + (iStart % 10) *9;
332        char[] chars = mid.toCharArray();
333        Integer iflag =8;
334        for(char c : chars) {
335            sum = sum + Integer.valueOf(c +"") * iflag;
336            iflag--;
337        }
338        return(sum % 10 == 0 ? 0: (10 - sum %10)) == Integer.valueOf(end) ?true : false;
339    }
340 
341    /**
342     * 验证香港身份证号码(存在Bug,部份特殊身份证无法检查)
343     * <p>
344     * 身份证前2位为英文字符,如果只出现一个英文字符则表示第一位是空格,对应数字58 前2位英文字符A-Z分别对应数字10-35
345     * 最后一位校验码为0-9的数字加上字符"A","A"代表10
346     * </p>
347     * <p>
348     * 将身份证号码全部转换为数字,分别对应乘9-1相加的总和,整除11则证件号码有效
349     * </p>
350     *
351     * @param idCard 身份证号码
352     * @return 验证码是否符合
353     */
354    publicstatic boolean validateHKCard(String idCard) {
355        String card = idCard.replaceAll("[\\(|\\)]","");
356        Integer sum =0;
357        if(card.length() == 9) {
358            sum = (Integer.valueOf(card.substring(0,1).toUpperCase().toCharArray()[0]) -55) * 9
359                    + (Integer.valueOf(card.substring(1,2).toUpperCase().toCharArray()[0]) -55) * 8;
360            card = card.substring(1,9);
361        } else {
362            sum =522 + (Integer.valueOf(card.substring(0,1).toUpperCase().toCharArray()[0]) -55) * 8;
363        }
364        String mid = card.substring(1,7);
365        String end = card.substring(7,8);
366        char[] chars = mid.toCharArray();
367        Integer iflag =7;
368        for(char c : chars) {
369            sum = sum + Integer.valueOf(c +"") * iflag;
370            iflag--;
371        }
372        if(end.toUpperCase().equals("A")) {
373            sum = sum +10;
374        } else {
375            sum = sum + Integer.valueOf(end);
376        }
377        return(sum % 11 == 0) ? true: false;
378    }
379 
380    /**
381     * 将字符数组转换成数字数组
382     *
383     * @param ca
384     *            字符数组
385     * @return 数字数组
386     */
387    publicstatic int[] converCharToInt(char[] ca) {
388        intlen = ca.length;
389        int[] iArr =new int[len];
390        try{
391            for(int i = 0; i < len; i++) {
392                iArr[i] = Integer.parseInt(String.valueOf(ca[i]));
393            }
394        } catch (NumberFormatException e) {
395            e.printStackTrace();
396        }
397        returniArr;
398    }
399 
400    /**
401     * 将身份证的每位和对应位的加权因子相乘之后,再得到和值
402     *
403     * @param iArr
404     * @return 身份证编码。
405     */
406    publicstatic int getPowerSum(int[] iArr) {
407        intiSum = 0;
408        if(power.length == iArr.length) {
409            for(int i = 0; i < iArr.length; i++) {
410                for(int j = 0; j < power.length; j++) {
411                    if(i == j) {
412                        iSum = iSum + iArr[i] * power[j];
413                    }
414                }
415            }
416        }
417        returniSum;
418    }
419 
420    /**
421     * 将power和值与11取模获得余数进行校验码判断
422     *
423     * @param iSum
424     * @return 校验位
425     */
426    publicstatic String getCheckCode18(intiSum) {
427        String sCode ="";
428        switch(iSum % 11) {
429        case10:
430            sCode ="2";
431            break;
432        case9:
433            sCode ="3";
434            break;
435        case8:
436            sCode ="4";
437            break;
438        case7:
439            sCode ="5";
440            break;
441        case6:
442            sCode ="6";
443            break;
444        case5:
445            sCode ="7";
446            break;
447        case4:
448            sCode ="8";
449            break;
450        case3:
451            sCode ="9";
452            break;
453        case2:
454            sCode ="x";
455            break;
456        case1:
457            sCode ="0";
458            break;
459        case0:
460            sCode ="1";
461            break;
462        }
463        returnsCode;
464    }
465 
466    /**
467     * 根据身份编号获取年龄
468     *
469     * @param idCard
470     *            身份编号
471     * @return 年龄
472     */
473    publicstatic int getAgeByIdCard(String idCard) {
474        intiAge = 0;
475        if(idCard.length() == CHINA_ID_MIN_LENGTH) {
476            idCard = conver15CardTo18(idCard);
477        }
478        String year = idCard.substring(6,10);
479        Calendar cal = Calendar.getInstance();
480        intiCurrYear = cal.get(Calendar.YEAR);
481        iAge = iCurrYear - Integer.valueOf(year);
482        returniAge;
483    }
484 
485    /**
486     * 根据身份编号获取生日
487     *
488     * @param idCard 身份编号
489     * @return 生日(yyyyMMdd)
490     */
491    publicstatic String getBirthByIdCard(String idCard) {
492        Integer len = idCard.length();
493        if(len < CHINA_ID_MIN_LENGTH) {
494            returnnull;
495        } else if (len == CHINA_ID_MIN_LENGTH) {
496            idCard = conver15CardTo18(idCard);
497        }
498        returnidCard.substring(6,14);
499    }
500 
501    /**
502     * 根据身份编号获取生日年
503     *
504     * @param idCard 身份编号
505     * @return 生日(yyyy)
506     */
507    publicstatic Short getYearByIdCard(String idCard) {
508        Integer len = idCard.length();
509        if(len < CHINA_ID_MIN_LENGTH) {
510            returnnull;
511        } else if (len == CHINA_ID_MIN_LENGTH) {
512            idCard = conver15CardTo18(idCard);
513        }
514        returnShort.valueOf(idCard.substring(6,10));
515    }
516 
517    /**
518     * 根据身份编号获取生日月
519     *
520     * @param idCard
521     *            身份编号
522     * @return 生日(MM)
523     */
524    publicstatic Short getMonthByIdCard(String idCard) {
525        Integer len = idCard.length();
526        if(len < CHINA_ID_MIN_LENGTH) {
527            returnnull;
528        } else if (len == CHINA_ID_MIN_LENGTH) {
529            idCard = conver15CardTo18(idCard);
530        }
531        returnShort.valueOf(idCard.substring(10,12));
532    }
533 
534    /**
535     * 根据身份编号获取生日天
536     *
537     * @param idCard
538     *            身份编号
539     * @return 生日(dd)
540     */
541    publicstatic Short getDateByIdCard(String idCard) {
542        Integer len = idCard.length();
543        if(len < CHINA_ID_MIN_LENGTH) {
544            returnnull;
545        } else if (len == CHINA_ID_MIN_LENGTH) {
546            idCard = conver15CardTo18(idCard);
547        }
548        returnShort.valueOf(idCard.substring(12,14));
549    }
550 
551    /**
552     * 根据身份编号获取性别
553     *
554     * @param idCard 身份编号
555     * @return 性别(M-男,F-女,N-未知)
556     */
557    publicstatic String getGenderByIdCard(String idCard) {
558        String sGender ="N";
559        if(idCard.length() == CHINA_ID_MIN_LENGTH) {
560            idCard = conver15CardTo18(idCard);
561        }
562        String sCardNum = idCard.substring(16,17);
563        if(Integer.parseInt(sCardNum) % 2!= 0) {
564            sGender ="M";
565        } else {
566            sGender ="F";
567        }
568        returnsGender;
569    }
570 
571    /**
572     * 根据身份编号获取户籍省份
573     *
574     * @param idCard 身份编码
575     * @return 省级编码。
576     */
577    publicstatic String getProvinceByIdCard(String idCard) {
578        intlen = idCard.length();
579        String sProvince =null;
580        String sProvinNum ="";
581        if(len == CHINA_ID_MIN_LENGTH || len == CHINA_ID_MAX_LENGTH) {
582            sProvinNum = idCard.substring(0,2);
583        }
584        sProvince = cityCodes.get(sProvinNum);
585        returnsProvince;
586    }
587 
588    /**
589     * 数字验证
590     *
591     * @param val
592     * @return 提取的数字。
593     */
594    publicstatic boolean isNum(String val) {
595        returnval == null || "".equals(val) ? false : val.matches("^[0-9]*$");
596    }
597 
598    /**
599     * 验证小于当前日期 是否有效
600     *
601     * @param iYear
602     *            待验证日期(年)
603     * @param iMonth
604     *            待验证日期(月 1-12)
605     * @param iDate
606     *            待验证日期(日)
607     * @return 是否有效
608     */
609    publicstatic boolean valiDate(int iYear, int iMonth, intiDate) {
610        Calendar cal = Calendar.getInstance();
611        intyear = cal.get(Calendar.YEAR);
612        intdatePerMonth;
613        if(iYear < MIN || iYear >= year) {
614            returnfalse;
615        }
616        if(iMonth < 1 || iMonth > 12) {
617            returnfalse;
618        }
619        switch(iMonth) {
620        case4:
621        case6:
622        case9:
623        case11:
624            datePerMonth =30;
625            break;
626        case2:
627            booleandm = ((iYear % 4 == 0 && iYear % 100!= 0) || (iYear %400 == 0))
628                    && (iYear > MIN && iYear < year);
629            datePerMonth = dm ?29 : 28;
630            break;
631        default:
632            datePerMonth =31;
633        }
634        return(iDate >= 1) && (iDate <= datePerMonth);
635    }
636}
0 0
原创粉丝点击