Java 判斷身份證Id是否合法
Java 判斷身份證Id是否合法,具體的還是以公安局的爲準,這裏只是做參考。
package utils;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.lang.StringUtils;
/**
* 身份證號碼驗證
* 1、號碼的結構
* 公民身份號碼是特徵組合碼,由十七位數字本體碼和一位校驗碼組成。排列順序從左至右依次爲:六位數字地址碼,
* 八位數字出生日期碼,三位數字順序碼和一位數字校驗碼。
* 2、地址碼(前六位數)
* 表示編碼對象常住戶口所在縣(市、旗、區)的行政區劃代碼,按GB/T2260的規定執行。
* 3、出生日期碼(第七位至十四位)
* 表示編碼對象出生的年、月、日,按GB/T7408的規定執行,年、月、日代碼之間不用分隔符。
* 4、順序碼(第十五位至十七位)
* 表示在同一地址碼所標識的區域範圍內,對同年、同月、同日出生的人編定的順序號,
* 順序碼的奇數分配給男性,偶數分配給女性。
* 5、校驗碼(第十八位數)
* (1)十七位數字本體碼加權求和公式 S = Sum(Ai * Wi), i = 0, , 16 ,先對前17位數字的權求和
* Ai:表示第i位置上的身份證號碼數字值 Wi:表示第i位置上的加權因子 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4
* 2 (2)計算模 Y = mod(S, 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 IDStr
* 身份證號
* @return 有效:返回"" 無效:返回String信息
* @throws ParseException
*/
public class IDCardValidate {
public static final String ACCEPT = "SUCCESS"; // 檢查通過是返回的的成功標識字符串
public static final int EIGHTEEN_IDCARD = 18; //標識18位身份證號碼
public static final int FIFTEEN_IDCARD = 15; //標識15位身份證號碼
public static final int MAX_MAINLAND_AREACODE = 659004; //大陸地區地域編碼最大值
public static final int MIN_MAINLAND_AREACODE = 110000; //大陸地區地域編碼最小值
public static final int HONGKONG_AREACODE = 810000; //香港地域編碼值
public static final int TAIWAN_AREACODE = 710000; //臺灣地域編碼值
public static final int MACAO_AREACODE = 820000; //澳門地域編碼值
/**
* 儲存18位身份證校驗碼
*/
private static final String[] SORTCODES = new String[]{"1","0","X","9","8","7","6","5","4","3","2"};
private static final Integer[] CHECK_NUMBERS = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
/**
* 驗證身份證主方法
*/
public static String chekIdCard(int sex, String idCardInput) {
if(StringUtils.isBlank(idCardInput)) {
return "身份證號碼爲必填";
}
if(idCardInput.length() != 18 && idCardInput.length() !=15 ) {
return "身份證號碼位數不符";
}
if(idCardInput.length() == 15) {
return checkIdCard15(sex,idCardInput);
}
return checkIdCard18(sex,idCardInput);
}
/**
* 驗證15位身份證號碼
*/
private static String checkIdCard15(int sex, String idCardInput) {
String numberResult = checkNumber(FIFTEEN_IDCARD,idCardInput);
if(!ACCEPT.equals(numberResult)) {
return numberResult;
}
String areaResult = checkArea(idCardInput);
if(!ACCEPT.equals(areaResult)) {
return areaResult;
}
String birthResult = checkBirthDate(FIFTEEN_IDCARD, idCardInput);
if(!ACCEPT.equals(birthResult)) {
return birthResult;
}
String checkCodeResult = checkCheckCode(FIFTEEN_IDCARD,idCardInput);
if(!ACCEPT.equals(checkCodeResult)) {
return checkCodeResult;
}
return ACCEPT;
}
/**
* 驗證18位身份證號碼
*/
private static String checkIdCard18(int sex, String idCardInput) {
String numberResult = checkNumber(EIGHTEEN_IDCARD,idCardInput);
if(!ACCEPT.equals(numberResult)) {
return numberResult;
}
String areaResult = checkArea(idCardInput);
if(!ACCEPT.equals(areaResult)) {
return areaResult;
}
String birthResult = checkBirthDate( EIGHTEEN_IDCARD, idCardInput);
if(!ACCEPT.equals(birthResult)) {
return birthResult;
}
String checkCodeResult = checkCheckCode(EIGHTEEN_IDCARD,idCardInput);
if( !ACCEPT.equals(checkCodeResult)) {
return checkCodeResult;
}
return ACCEPT;
}
/**
* 驗證身份證的地域編碼是符合規則
*/
private static String checkArea(String idCardInput) {
String subStr = idCardInput.substring(0, 6);
int areaCode = Integer.parseInt(subStr);
if( areaCode != HONGKONG_AREACODE && areaCode != TAIWAN_AREACODE && areaCode != MACAO_AREACODE
&& ( areaCode > MAX_MAINLAND_AREACODE || areaCode < MIN_MAINLAND_AREACODE) ) {
return "輸入的身份證號碼地域編碼不符合大陸和港澳臺規則";
}
return ACCEPT;
}
/**
* 驗證身份證號碼數字字母組成是否符合規則
*/
private static String checkNumber(int idCardType ,String idCard) {
char[] chars = idCard.toCharArray();
if(idCardType == FIFTEEN_IDCARD){
for(int i = 0; i<chars.length;i++){
if( chars[i] > '9' ) {
return idCardType+"位身份證號碼中不能出現字母";
}
}
}else{
for(int i = 0; i < chars.length; i++) {
if( i < chars.length-1 ){
if( chars[i] > '9' ) {
return EIGHTEEN_IDCARD+"位身份證號碼中前"+(EIGHTEEN_IDCARD-1)+"不能出現字母";
}
}else{
if( chars[i] > '9' && chars[i] != 'X') {
return idCardType+"位身份證號碼中最後一位只能是數字0~9或字母X";
}
}
}
}
return ACCEPT;
}
/**
* 驗證身份證號碼出生日期是否符合規則
*/
private static String checkBirthDate(int idCardType, String idCardInput){
String yearResult = checkBirthYear(idCardType,idCardInput);
if(!ACCEPT.equals(yearResult)) {
return yearResult;
}
String monthResult = checkBirthMonth(idCardType,idCardInput);
if( !ACCEPT.equals(monthResult)) {
return monthResult;
}
String dayResult = checkBirthDay(idCardType,idCardInput);
if( !ACCEPT.equals(dayResult)) {
return dayResult;
}
return ACCEPT;
}
/**
* 驗證身份證號碼出生日期年份是否符合規則
*/
private static String checkBirthYear(int idCardType, String idCardInput){
if( idCardType == FIFTEEN_IDCARD){
int year = Integer.parseInt(idCardInput.substring(6, 8));
if( year < 0 || year > 99 ) {
return idCardType+"位的身份證號碼年份須在00~99內";
}
}else{
int year = Integer.parseInt(idCardInput.substring(6, 10));
int yearNow = getYear();
if( year < 1900 || year > yearNow ) {
return idCardType+"位的身份證號碼年份須在1900~"+yearNow+"內";
}
}
return ACCEPT;
}
/**
* 驗證身份證號碼出生日期月份是否符合規則
*/
private static String checkBirthMonth(int idCardType, String idCardInput){
int month = 0;
if( idCardType == FIFTEEN_IDCARD) {
month = Integer.parseInt(idCardInput.substring(8, 10));
}else {
month = Integer.parseInt(idCardInput.substring(10, 12));
}
if( month < 1 || month > 12) {
return "身份證號碼月份須在01~12內";
}
return ACCEPT;
}
/**
* 驗證身份證號碼出生日期天數是否符合規則
*/
private static String checkBirthDay(int idCardType, String idCardInput){
boolean bissextile = false;
int year,month,day;
if( idCardType == FIFTEEN_IDCARD){
year = Integer.parseInt("19"+idCardInput.substring(6, 8));
month = Integer.parseInt(idCardInput.substring(8, 10));
day = Integer.parseInt(idCardInput.substring(10, 12));
}else{
year = Integer.parseInt(idCardInput.substring(6, 10));
month = Integer.parseInt(idCardInput.substring(10, 12));
day = Integer.parseInt(idCardInput.substring(12, 14));
}
if(year%4 == 0 && year%100 != 0 || year%400 ==0 ) {
bissextile = true;
}
switch( month ) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if( day < 1 || day > 31 )
return "身份證號碼大月日期須在1~31之間";
break;
case 4:
case 6:
case 9:
case 11:
if( day < 1 || day > 30 )
return "身份證號碼小月日期須在1~30之間";
break;
case 2:
if(bissextile){
if( day < 1 || day > 29 )
return "身份證號碼閏年2月日期須在1~29之間";
}else {
if( day < 1 || day > 28 )
return "身份證號碼非閏年2月日期年份須在1~28之間";
}
break;
}
return ACCEPT;
}
/**
* 驗證18位身份證號碼校驗碼是否符合規則
*/
private static String checkCheckCode( int idCardType , String idCard ){
if( idCardType == EIGHTEEN_IDCARD ){
int sigma = 0;
for (int i=0; i<17; i++) {
int ai = Integer.parseInt(idCard.substring(i,i+1));
int wi = CHECK_NUMBERS[i];
sigma += ai * wi;
}
int number = sigma % 11;
String check_number = SORTCODES[number];
if(!check_number.equals(idCard.substring(17))) {
return "身份中的校驗碼不正確";
}
}
return ACCEPT;
}
/**
* 返回當前年份
*/
private static int getYear(){
Date now = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyymmdd");
String nowStr = format.format(now);
return Integer.parseInt(nowStr.substring(0, 4));
}
public static void main(String[]args) {
System.out.println(chekIdCard(2, "441522199101024749"));
}
}