package com.rainteen.framework.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @version
*/
public class IDCard {
/**
* @param idCard
*/
public static boolean isValidIdCardNoOfCN(String idCard)
{
final String regLeapMonthDay15="^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$";
final String regNormalMonthDay15="^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$";
final String regLeapMonthDay18="^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$";
final String regNormalMonthDay18="^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$";
String[] msg={ "通过校验",
"身份证号码位数不对!",
"身份证号码出生日期超出范围或含有非法字符!",
"身份证号码校验错误!",
"身份证地区非法!" };
if(idCard==null || "".equals(idCard.trim()))
return false;
idCard=idCard.trim().toUpperCase();
//System.err.println("idCard:"+idCard);
String[][] area={{"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", "国外"}};
String areaCode=idCard.trim().substring(0,2);
//System.err.println("areaCode:"+areaCode);
boolean correctArea=false;
for(int i=0; i<area.length; i++){
for(int j=0; j<area[i].length; j++){
if(areaCode.equals(area[i][0])){
correctArea=true;
break;
}
}
}
if(!correctArea){
System.err.println(msg[3]);
return false;
}
Pattern pattern=null;
Matcher matcher=null;
switch(idCard.trim().length()){
case 15:
pattern=Pattern.compile(regLeapMonthDay15);
//
String birthday=idCard.substring(5,12);
//System.err.println("birthday:"+birthday);
String year=(1900+Integer.parseInt(birthday.substring(0,2)))+"";
matcher=pattern.matcher(year+birthday.substring(2));
if(matcher.matches()){ //
return true;
}else{
Pattern.compile(regNormalMonthDay15);
matcher=pattern.matcher(birthday);
if(matcher.matches()){ //
return true;
}else{
System.err.println(msg[2]);
return false;
}
}
case 18: //18λ
pattern=Pattern.compile(regLeapMonthDay18);
/*
String birth=idCard.substring(6,14);
System.err.println("birth:"+birth);
*/
matcher=pattern.matcher(idCard);
if(matcher.matches()){
return checkIDCard(idCard);
}else{
Pattern.compile(regNormalMonthDay18);
matcher=pattern.matcher(idCard);
if(matcher.matches()){
return checkIDCard(idCard);
}else{
System.err.println(msg[2]);
return false;
}
}
default:
System.err.println(msg[1]);
}
return false;
}
/**
*/
private static boolean checkIDCard(String idCard){
char[] bit=idCard.toCharArray();
int s= ((int)(bit[0]-48)+(int)(bit[10]-48))*7+
((int)(bit[1]-48)+(int)(bit[11]-48))*9+
((int)(bit[2]-48)+(int)(bit[12]-48))*10+
((int)(bit[3]-48)+(int)(bit[13]-48))*5+
((int)(bit[4]-48)+(int)(bit[14]-48))*8+
((int)(bit[5]-48)+(int)(bit[15]-48))*4+
((int)(bit[6]-48)+(int)(bit[16]-48))*2+
((int)(bit[7]-48))*1+
((int)(bit[8]-48))*6+
((int)(bit[9]-48))*3;
int checkBit=s%11; //
char m='F';
String jym="10X98765432"; //check sum
m=jym.charAt(checkBit); //
if(m==bit[17]) return true;
else{
return false;
}
}
/**
* @param seventeenNo
* @return
*/
public static String getParityBit(String seventeenNo){
char[] bit=seventeenNo.toCharArray();
int s= ((int)(bit[0]-48)+(int)(bit[10]-48))*7+
((int)(bit[1]-48)+(int)(bit[11]-48))*9+
((int)(bit[2]-48)+(int)(bit[12]-48))*10+
((int)(bit[3]-48)+(int)(bit[13]-48))*5+
((int)(bit[4]-48)+(int)(bit[14]-48))*8+
((int)(bit[5]-48)+(int)(bit[15]-48))*4+
((int)(bit[6]-48)+(int)(bit[16]-48))*2+
((int)(bit[7]-48))*1+
((int)(bit[8]-48))*6+
((int)(bit[9]-48))*3;
int checkBit=s%11; //
char m='F';
String jym="10X98765432"; //check sum
m=jym.charAt(checkBit); //
return m+"";
}
/**
* @param fifteenIDCard
* @param century
* @return
*/
private static String fifteenToEighteen(String fifteenIDCard, int century){
if( fifteenIDCard==null || "".equals(fifteenIDCard) ||
fifteenIDCard.length()!=15 || !(20<=century && century<=21)){
throw new RuntimeException("");
}
String eighteen=fifteenIDCard.substring(0,6);
eighteen+=(century-1)+"";
eighteen+=fifteenIDCard.substring(6,15);
eighteen+=getParityBit(eighteen);
return eighteen;
}
/**
* @param fifteenIDCard
* @return
*/
public static String fifteenToEighteen(String fifteenIDCard){
return fifteenToEighteen(fifteenIDCard, 20);
}
/**
* @param eighteenIDCard
* @return
*/
public static String eighteenToFifteen(String eighteenIDCard){
if( eighteenIDCard==null || "".equals(eighteenIDCard.trim()) ||
eighteenIDCard.length()!=18 || !isValidIdCardNoOfCN(eighteenIDCard)){
throw new IllegalArgumentException("Id card number is invalid.");
}
String fifteenIDCard=eighteenIDCard.substring(0,6);
fifteenIDCard+=eighteenIDCard.substring(8, 17);
return fifteenIDCard;
}
/**
* @param args
*/
public static void main(String[] args) {
System.out.println(fifteenToEighteen("642123781121151"));
System.out.println(eighteenToFifteen("642123197811211518"));
}
}