package com.clark.test.idcard; /** * 测试校验身份证合法性的小程序 * <p>我们常用的身份证号码为18位或者15位</p> <p>下面的程序仅仅用于校验18为的身份证的合法性</p> * @author caolipeng * @date 2015年1月9日 上午10:27:13 * @Version 1.0 */ public class IDCardValidator { <span style="color:#ff0000;">/**17位数字的本体码权重*/</span> private static final int[] weight = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2}; <span style="color:#ff0000;">/**求和之后mod 11的对应最后一位合法位的字符,下标分别为Y: 0 1 2 3 4 5 6 7 8 9 10 */</span> private static final char[] validate = {'1','0','X','9','8','7','6','5','4','3','2'}; /** * 校验身份证是否合法 * @param idCard 输入需要校验的身份证号码(仅仅位18位长度的时候) * @return true:合法,false:非法 */ private static boolean isValidIDCard(String idCard){ boolean flag = false; //得到身份证号码最后一位 char lastStr = idCard.charAt(idCard.length()-1); //判断输入的身份证号码是否包含非数字字符 boolean isValid = ValidateUtil.isNumberOrLetterX(idCard); if(!isValid){ System.out.println("输入的身份证"+idCard+",含有非数字字符(或者最后一位字符不是'X')"); return flag; } //校验地区码是否合法 boolean areaValid = ValidateUtil.isValidAreaCode(idCard); if(!areaValid){ System.out.println("身份证地区码"+idCard.substring(0,2)+"无效"); return flag; } //校验年月日是否合法 Boolean dateOfBirth = ValidateUtil.isValidDateOfBirth(idCard); if(!dateOfBirth){ return flag; } //得到经过校验之后的最后一位合法的char char result = getIDCard18LastBit(idCard); System.out.println(result); if(lastStr ==result){ flag = true; } return flag; } <span style="color:#ff0000;">/** * 获取身份证最后一位校验位的算法为: * (1)十七位数字本体码加权求和公式 (其中,第17位为表示男:奇数,女:偶数) * S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和 * Ai:表示第i位置上的身份证号码数字值(0~9) * Wi:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 (表示第i位置上的加权因子) * (2)计算模 Y = mod(S, 11),Y=S mod 11 * (3)根据模,查找得到对应的校验码 * Y: 0 1 2 3 4 5 6 7 8 9 10 * 校验码: 1 0 X 9 8 7 6 5 4 3 2 * @param idCard 输入需要校验的身份证号码(仅仅位18位长度的时候) * @return 最后一位校验位 */</span> private static char getIDCard18LastBit(String idCard){ char init = 'E'; int length = idCard!=null?idCard.length():0;//获得输入身份证号码长度 if(length==18){//18位或者15位 String subIdCard = idCard.substring(0, 17); int subLength = subIdCard.length();//获得前17位 char[] temp = subIdCard.toCharArray();//存放每一位字符串的字符数组 //得到每一位的char转换成字符串数组 String str[] = new String[subLength]; for (int i = 0; i < str.length; i++) { str[i] = temp[i]+""; } //(1)计算十七位数字本体码加权求和 int sum = 0; for (int i = 0; i < str.length; i++) { sum += Integer.parseInt(str[i])*weight[i]; } //(2)计算模 Y = mod(S, 11),Y=S mod 11 int modResult = sum%11; //(3)根据模,查找得到对应的校验码 init = validate[modResult]; } return init;//默认返回E位错误结果 } /** * 15位身份证转成18位 * @param idCard 15位长度的身份证号码 * @return 对应的18位身份证号码的最后一位合法位 */ private static char change15To18IDCard(String idCard){ String temp = idCard; if(idCard.length()==15){//15位(可以算出它对应的18位身份证号码) 年份补19--世纪 例如62--1962,最后一位任意补一个字符 temp = idCard.substring(0, 6)+"19"+idCard.substring(6,15)+"X"; } //得到15位身份证转化后的最后一位合法位 char lastBit = getIDCard18LastBit(temp); return lastBit; } public static void main(String[] args) { /**18位的测试*/ String idCard = "431023199201161801"; boolean result = isValidIDCard(idCard); System.out.println(result); /**15位测试*/ /*String idCard15 = "431023520516182"; boolean res15= ValidateUtil.isValidNumber15(idCard15); System.out.println(res15); char id = change15To18IDCard(idCard15); System.out.println(id);*/ } }
package com.clark.test.idcard; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 校验身份证号码的工具类 * @author caolipeng * @date 2015年1月9日 下午2:31:24 * @Version 1.0 */ public class ValidateUtil { /** * 功能:设置地区编码 * @return Map<String,Object> 对象 */ private static Map<String,Object> getAreaCode() { Map<String,Object> areaCodeMap = new HashMap<String,Object>(); areaCodeMap.put("11", "北京"); areaCodeMap.put("12", "天津"); areaCodeMap.put("13", "河北"); areaCodeMap.put("14", "山西"); areaCodeMap.put("15", "内蒙古"); areaCodeMap.put("21", "辽宁"); areaCodeMap.put("22", "吉林"); areaCodeMap.put("23", "黑龙江"); areaCodeMap.put("31", "上海"); areaCodeMap.put("32", "江苏"); areaCodeMap.put("33", "浙江"); areaCodeMap.put("34", "安徽"); areaCodeMap.put("35", "福建"); areaCodeMap.put("36", "江西"); areaCodeMap.put("37", "山东"); areaCodeMap.put("41", "河南"); areaCodeMap.put("42", "湖北"); areaCodeMap.put("43", "湖南"); areaCodeMap.put("44", "广东"); areaCodeMap.put("45", "广西"); areaCodeMap.put("46", "海南"); areaCodeMap.put("50", "重庆"); areaCodeMap.put("51", "四川"); areaCodeMap.put("52", "贵州"); areaCodeMap.put("53", "云南"); areaCodeMap.put("54", "西藏"); areaCodeMap.put("61", "陕西"); areaCodeMap.put("62", "甘肃"); areaCodeMap.put("63", "青海"); areaCodeMap.put("64", "宁夏"); areaCodeMap.put("65", "新疆"); areaCodeMap.put("71", "台湾"); areaCodeMap.put("81", "香港"); areaCodeMap.put("82", "澳门"); areaCodeMap.put("91", "国外"); return areaCodeMap; } /** * 功能:校验地区码是否合法 * @param idCard 身份证号码 * @return true:合法,false:非法 */ public static boolean isValidAreaCode(String idCard){ String areaCode = idCard.substring(0,2); Map<String,Object> map = getAreaCode(); boolean flag = map.containsKey(areaCode); return flag; } /** * @param idCard 身份证号码 * @return true:数字,false:含有非数字 */ public static boolean isNumberOrLetterX(String idCard){ boolean flag = false; Pattern p = Pattern.compile("[0-9]*(X)?"); Matcher m = p.matcher(idCard); if(m.matches()){ flag=true; } return flag; } /** * 校验输入的身份证号码是否都是数字 * @param idCard 身份证号码 * @return true:数字,false:含有非数字 */ public static boolean isValidNumber15(String idCard){ boolean flag = false; if(idCard.length()!=15){ System.out.println("身份证号码长度必须为15"); return flag; } Pattern p = Pattern.compile("[0-9]*"); Matcher m = p.matcher(idCard); if(m.matches()){ flag=true; } return flag; } /** * 功能:校验身份证号码的出生年-月-日是否合法 * @param idCard 身份证号码 * @return 合法与否 */ public static boolean isValidDateOfBirth(String idCard){ Boolean flag = true; int year = Integer.parseInt(idCard.substring(6,10)); int month = Integer.parseInt(idCard.substring(10, 12)); int day = Integer.parseInt(idCard.substring(12,14)); //年份的话,仅仅设定区间为向前200年 Date date = new Date(); SimpleDateFormat simple = new SimpleDateFormat("YYYY"); String formatDate = simple.format(date); int nowYear = Integer.parseInt(formatDate); if(year<nowYear-200 || year>nowYear){ flag = false; System.out.println("年份"+year+"不在【"+(nowYear-200)+","+nowYear+"】之间"); } if(month>12 || month<1){ flag = false; System.out.println("月份"+month+"不在【01-12】之间"); } if(day>31 || day<1){ flag = false; System.out.println("日"+day+"不在【01-31】之间"); } return flag; } }
时间: 2024-11-09 08:21:42