Java身份證認證
/**
* 身份證驗證
*
*/
public class CheckIdCard {
// 檢查通過是返回的的成功標識字符串
public static final String ACCEPT = "";
// 標識18位身份證號碼
public static final int EIGHTEEN_IDCARD = 18;
// 標識15位身份證號碼
public static final int FIFTEEN_IDCARD = 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;
// 標識男性
private static final int MAN_SEX = 1;
// 標識女性
private static final int WOMAN_SEX = 2;
// 儲存18位身份證校驗碼
private static final String[] SORTCODES = new String[] { "1", "0", "X",
"9", "8", "7", "6", "5", "4", "3", "2" };
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String idCard = "142424870329324";
String result = chekIdCard(1, idCard);
if ("".equals(result))
System.out.println("身份證合法");
else
System.out.println(result);
}
/**
* 驗證身份證主方法
*/
public static String chekIdCard(int sex, String idCardInput) {
if (idCardInput == null || "".equals(idCardInput))
return "身份證號碼爲必填";
if (idCardInput.length() != 18 && idCardInput.length() != 15)
return "身份證號碼位數不符";
if (idCardInput.length() == 15)
return checkIdCard15(sex, idCardInput);
else
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 sortCodeResult = checkSortCode(FIFTEEN_IDCARD, sex, idCardInput);
if (!ACCEPT.equals(sortCodeResult))
return sortCodeResult;
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 sortCodeResult = checkSortCode(EIGHTEEN_IDCARD, sex, idCardInput);
if (!ACCEPT.equals(sortCodeResult))
return sortCodeResult;
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;
}
/**
* 驗證身份證號碼順序碼是否符合規則,男性爲偶數,女性爲奇數
*/
private static String checkSortCode(int idCardType, int sex,
String idCardInput) {
int sortCode = 0;
if (idCardType == FIFTEEN_IDCARD) {
sortCode = Integer.parseInt(idCardInput.substring(12, 15));
} else {
sortCode = Integer.parseInt(idCardInput.substring(14, 17));
}
if (sex == MAN_SEX) {
if (sortCode % 2 == 0)
return "男性的身份證順序碼須爲奇數";
} else {
if (sortCode % 2 != 0)
return "女性的身份證順序碼須爲偶數";
}
return ACCEPT;
}
/**
* 驗證18位身份證號碼校驗碼是否符合規則
*/
private static String checkCheckCode(int idCardType, String idCard) {
if (idCardType == EIGHTEEN_IDCARD) {
int sum = 0;
char[] chars = idCard.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (i == 0)
sum = sum + (chars[i] * 7);
if (i == 1)
sum = sum + (chars[i] * 9);
if (i == 2)
sum = sum + (chars[i] * 10);
if (i == 3)
sum = sum + (chars[i] * 5);
if (i == 4)
sum = sum + (chars[i] * 5);
if (i == 5)
sum = sum + (chars[i] * 8);
if (i == 6)
sum = sum + (chars[i] * 4);
if (i == 7)
sum = sum + (chars[i] * 1);
if (i == 8)
sum = sum + (chars[i] * 6);
if (i == 9)
sum = sum + (chars[i] * 3);
if (i == 10)
sum = sum + (chars[i] * 7);
if (i == 11)
sum = sum + (chars[i] * 9);
if (i == 12)
sum = sum + (chars[i] * 10);
if (i == 13)
sum = sum + (chars[i] * 5);
if (i == 14)
sum = sum + (chars[i] * 8);
if (i == 15)
sum = sum + (chars[i] * 4);
if (i == 16)
sum = sum + (chars[i] * 2);
}
int checkCode = sum % 11;
String sortCode = SORTCODES[checkCode];
if (!sortCode.equals(String.valueOf(chars[chars.length - 1])))
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));
}
}