Java实现⾝份证合法性校验(包含港澳台地区)
在做项⽬过程中针对⾃然⼈数据⼊库前⼀般是要进⾏⾝份证的合法性校验,或者在表单提交到后端的时候进⾏验证,当⾝份证号输⼊错误以便给于⽤户友好的提⽰(也可以根据⾝份证号同时校验表单中性别和出⽣⽇期等),验证主要是防⽌⽆效数据⼊库。
如果数据对接了公安局或者银⾏也可以进⾏姓名等的验证,在调⽤公安局或者银⾏的接⼝时⼀般是要先进⾏⾝份证的合法性校验,可以提升⽤户体验,在⽤户输⼊错误时及时反馈⽽不必等待公安局或者银⾏接⼝结果的返回。
本⽂提供了中国⼤陆⼀代⾝份证、中国⼤陆⼆代⾝份证、中国港澳台⾝份证的合法性校验,以及通过⾝份证获取年龄、性别、出⽣⽇期等信息。
⼀代⾝份证与⼆代⾝份证的区别
1. ⼀代⾝份证是15位,⼆代⾝份证是18位;
2. ⼀代⾝份证出⽣年⽉⽇采⽤YYMMDD格式,⼆代⾝份证出⽣年⽉⽇采⽤YYYYMMDD格式;
3. ⼀代⾝份证⽆校验码,⼆代⾝份证有校验码。
⼆代⾝份证号码的编码规则
1. ⾝份证号码前六位:表⽰编码对象常住户⼝所在县(市、镇、区)的⾏政区划代码。1-2位省、⾃治区、直辖市代码; 3-4位地级市、
盟、⾃治州代码; 5-6位县、县级市、区代码;
2. ⾝份证号码第七位到第⼗四位:表⽰编码对象出⽣的年、⽉、⽇,其中年份⽤四位数字表⽰年、⽉、⽇之间不⽤分隔符,采⽤
张嘉倪老公
YYYYMMDD格式;
3. ⾝份证号码第⼗五位到⼗七位:地址码所标识的区域范围内,对同年、⽉、⽇出⽣的⼈员编定的顺序号。顺序码的奇数分配给男性,偶
数分配给⼥性,即第17位奇数表⽰男性,偶数表⽰⼥性;
4. ⾝份证号码最后⼀位:根据前⾯⼗七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。如果某⼈的尾号是0-9,
都不会出现X,但如果尾号是10,那么就得⽤X来代替,X是罗马数字的10,⽤X来代替10,可以保证公民的⾝份证符合国家标准;⼆代⾝份证校验规则(最后⼀位校验码的计算⽅法)
⾸先将前⾯的⾝份证号码17位数分别乘以不同的系数。从第⼀位到第⼗七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2
接下来将这17位数字和系数相乘的结果相加,然后⽤加出来和除以11,看余数,余数只可能有0-1-2-3-4-5-6-7-8-9-10这11个数字。其分别对应的最后⼀位⾝份证的号码为1-0-X -9-8-7-6-5-4-3-2
Java代码实现
package com.aiwen.utils;
ParseException;
SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* ⾝份证⼯具类
*
*/
public class IDCardUtil {农合医疗2023交费
/** 中国公民⼀代⾝份证号码长度。 */
public static final int CHINA_ID_MIN_LENGTH =15;
/** 中国公民⼆代⾝份证号码长度。 */
public static final int CHINA_ID_MAX_LENGTH =18;
/
**  数据字典-性别男    */
public static final String SEX_CODE_OF_MAN="1";
/**  数据字典-性别⼥    */
public static final String SEX_CODE_OF_FEMALE="0";
/** 省、直辖市代码表 */
public static final String cityCode[]={
"11","12","13","14","15","21","22","23","31","32","33","34","35","36","37","41", "42","43","44","45","46","50","51","52","53","54","61","62","63","64","65","71", "81","82","91"
};
/** 每位加权因⼦ */
public static final int power[]={
7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2
};
/** 第18位校检码 */
public static final String verifyCode[]={
"1","0","X","9","8","7","6","5","4","3","2"
};
财务工作个人总结/** 最低年限 */
public static final int MIN =1930;
public static Map<String, String> cityCodes =new HashMap<String, String>();
/** 台湾⾝份⾸字母对应数字 */
华硕a45v
public static Map<String, Integer> twFirstCode =new HashMap<String, Integer>();
/** ⾹港⾝份⾸字母对应数字 */
public static Map<String, Integer> hkFirstCode =new HashMap<String, Integer>();
static{
cityCodes.put("11","北京");
cityCodes.put("12","天津");
cityCodes.put("13","河北");
cityCodes.put("14","⼭西");
cityCodes.put("15","内蒙古");
cityCodes.put("21","辽宁");
cityCodes.put("22","吉林");
cityCodes.put("23","⿊龙江");
cityCodes.put("31","上海");
cityCodes.put("32","江苏");
cityCodes.put("33","浙江");
cityCodes.put("34","安徽");
cityCodes.put("35","福建");
cityCodes.put("36","江西");
cityCodes.put("37","⼭东");
cityCodes.put("41","河南");
cityCodes.put("42","湖北");
cityCodes.put("43","湖南");
cityCodes.put("44","⼴东");
cityCodes.put("45","⼴西");
cityCodes.put("46","海南");
cityCodes.put("50","重庆");
cityCodes.put("51","四川");
cityCodes.put("52","贵州");
cityCodes.put("53","云南");
cityCodes.put("54","西藏");
cityCodes.put("61","陕西");
cityCodes.put("62","⽢肃");
cityCodes.put("63","青海");
cityCodes.put("64","宁夏");
cityCodes.put("65","新疆");
cityCodes.put("71","台湾");
cityCodes.put("81","⾹港");
cityCodes.put("82","澳门");
cityCodes.put("91","国外");
twFirstCode.put("A",10);
twFirstCode.put("B",11);
twFirstCode.put("C",12);
twFirstCode.put("D",13);
twFirstCode.put("E",14);
twFirstCode.put("F",15);
twFirstCode.put("G",16);
twFirstCode.put("H",17);
twFirstCode.put("J",18);
twFirstCode.put("K",19);
twFirstCode.put("L",20);
twFirstCode.put("M",21);
twFirstCode.put("N",22);
twFirstCode.put("P",23);
twFirstCode.put("Q",24);
twFirstCode.put("R",25);
twFirstCode.put("S",26);
twFirstCode.put("T",27);
twFirstCode.put("U",28);
twFirstCode.put("V",29);
twFirstCode.put("X",30);
twFirstCode.put("Y",31);
twFirstCode.put("W",32);
twFirstCode.put("Z",33);
twFirstCode.put("I",34);
twFirstCode.put("O",35);
hkFirstCode.put("A",1);
hkFirstCode.put("B",2);
hkFirstCode.put("C",3);
hkFirstCode.put("R",18);
hkFirstCode.put("U",21);
hkFirstCode.put("Z",26);
hkFirstCode.put("X",24);
hkFirstCode.put("W",23);
hkFirstCode.put("O",15);
hkFirstCode.put("N",14);
}
/**
* 验证⾝份证是否合法,只验证内地
*/
public static boolean validateCard(String idCard){    String card =toNotNullString(idCard).trim();
if(validateIdCard18(card)){
return true;
}
if(validateIdCard15(card)){
return true;
}
return false;
}
/**
* 验证⾝份证是否合法包括台湾、⾹港、澳门
*/
public static boolean validateAllCard(String idCard){    String card =toNotNullString(idCard).trim();
if(validateIdCard18(card)){
return true;
}
if(validateIdCard15(card)){
return true;
}
String[] cardval =validateIdCard10(card);
if(cardval != null){
if(cardval[2].equals("true")){
if(cardval[2].equals("true")){
return true;
}
}
return false;
}
/**
* 获取出⽣年⽉
* @param SrcIDCard ⾝份证号码
* @return YYYY-MM-DD
*/
public static String getBirthday(String SrcIDCard){
String IDCard =toNotNullString(SrcIDCard).trim();
if(!validateCard(IDCard)){
return"";
}
int lenOfCardID = IDCard.length();
if(CHINA_ID_MIN_LENGTH == lenOfCardID){
IDCard =conver15CardTo18(IDCard);
}
String year=IDCard.substring(6,10);
String month=IDCard.substring(10,12);
String day=IDCard.substring(12,14);
return year +"-"+ month +"-"+ day;
}
/**
* 获取出⽣年份
* @param SrcIDCard
* @return
*/
public static Long getYearByIdcard(String SrcIDCard){
String IDCard =toNotNullString(SrcIDCard).trim();
if(!validateCard(IDCard)){
return null;
}
int lenOfCardID = IDCard.length();
if(CHINA_ID_MIN_LENGTH == lenOfCardID){
IDCard =conver15CardTo18(IDCard);
}
String year=IDCard.substring(6,10);
return Long.valueOf(year);
}
/**
* 获取⽇期类型的出⽣⽇期
* @param SrcIDCard
* @return
* @throws ParseException
*/
public static Date getBirthdayOfDate(String SrcIDCard){
String birth =getBirthday(SrcIDCard);
Date birthday = null;
try{
if(birth !=""&& birth != null){
birthday =new SimpleDateFormat("yyyy-MM-dd").parse(birth); }
}catch(ParseException e){
return birthday;
}
return birthday;
}
马沂茹
/**
* 获取性别
* @param SrcIDCard ⾝份证号码
* @return 1-男 0-⼥
* @return 1-男 0-⼥
*/
public static String getSex(String SrcIDCard){
String IDCard =toNotNullString(SrcIDCard).trim();
int lenOfCardID = IDCard.length();
String sex ="";
if(!validateCard(IDCard)){
return null;
}
if(lenOfCardID == CHINA_ID_MIN_LENGTH){
IDCard =conver15CardTo18(IDCard);
}
String sexFlag=IDCard.substring(16,17);
if(Integer.parseInt(sexFlag)%2==0)
{
sex = SEX_CODE_OF_FEMALE;
}else{
sex = SEX_CODE_OF_MAN;
}
return sex;
}
/**
*获取年龄
*@param SrcIDCard ⾝份证号码
*/
public static String getAge(String SrcIDCard){
Date birthday =getBirthdayOfDate(SrcIDCard);
if(birthday==null)return"";
Calendar c1 = Instance();
long nowmillSeconds = c1.getTimeInMillis();
Calendar c2 = Instance();
c2.setTime(birthday);
long birmillSeconds = c2.getTimeInMillis();元旦法定假日是几天?
Calendar c3 = Instance();
long millis = nowmillSeconds - birmillSeconds;
c3.setTimeInMillis(millis);
int year = c3.get(Calendar.YEAR);
if(year >=1970){
return(year -1970)+"";
}else{
return"";
}
}
/**
* 将15位⾝份证号码转换为18位
*
* @param idCard
*            15位⾝份编码
* @return 18位⾝份编码
*/
public static String conver15CardTo18(String idCard){
String idCard18 ="";
if(idCard.length()!= CHINA_ID_MIN_LENGTH){
return null;
}
if(isNum(idCard)){
// 获取出⽣年⽉⽇
String birthday = idCard.substring(6,12);
Date birthDate = null;
try{
birthDate =new SimpleDateFormat("yyMMdd").parse(birthday);
}catch(ParseException e){
e.printStackTrace();
}
Calendar cal = Instance();
if(birthDate != null)