Java ID card validity verification tool class

package com.idc.util;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * <p>
 * ID verification
 *</p>
 *
 * <pre>
 * --15-digit ID card number: the 7th and 8th digits are the year of birth (two digits), the 9th and 10th digits are the month of birth, the 11th and 12th digits represent the date of birth, the 15th digit represents gender, and odd numbers are male , the even number is female.
 * --18-digit ID card number: the 7th, 8th, 9th, and 10th digits are the year of birth (four digits), the 11th and 12th digits are the month of birth, the 13th and 14th digits represent the date of birth, and the 17th digit represents Gender, odd numbers are male, even numbers are female.
 * The last digit is the check digit
 * 

*
* @author 313921
*/
public class IdCardUtil {

private static Logger logger = LoggerFactory. getLogger(IdCardUtil. class);

/**
*

     * Code list of provinces and municipalities directly under the Central Government:
     * 11: Beijing 12: Tianjin 13: Hebei 14: Shanxi 15: Inner Mongolia
     * 21: Liaoning 22: Jilin 23: Heilongjiang 31: Shanghai 32: Jiangsu
     * 33: Zhejiang 34: Anhui 35: Fujian 36: Jiangxi 37: Shandong
     * 41 : Henan 42 : Hubei 43 : Hunan 44 : Guangdong 45 : Guangxi 46 : Hainan
     * 50 : Chongqing 51 : Sichuan 52 : Guizhou 53 : Yunnan 54 : Tibet
     * 61 : Shaanxi 62 : Gansu 63 : Qinghai 64 : Ningxia 65 : Xinjiang
     * 71 : Taiwan
     * 81 : Hong Kong 82 : Macau
     * 91 : Abroad
     * 

*/
private static 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” };

/**
* Each weighting factor
*/
private static int power[] = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5,
8, 4, 2 };

/**
* Verify the legitimacy of all ID cards
*
* @param idcard
* ID card
* @return legally return true, otherwise return false
*/
public static boolean isValidatedAllIdcard(String idcard) {
if (idcard == null || “”.equals(idcard)) {
return false;
}
if (idcard. length() == 15) {
return validate15IDCard(idcard);
}
if(idcard. length()==18) {
return validate18Idcard(idcard);
}
return false;

}

/**
*

* Judging the legitimacy of the 18-digit ID card
*

*According to the stipulations on citizen identity number in the National Standard of the People’s Republic of China GB11643-1999, the citizen identity number is a feature combination code consisting of a 17-digit body code and a one-digit check code.
* The arrangement order from left to right is: six-digit address code, eight-digit date of birth code, three-digit sequential code and one-digit check code.
*

* Sequence code: Indicates the sequence number assigned to people born in the same year, month, and day within the area identified by the same address code. The odd number of the sequence code is allocated to males, and the even number is allocated to females.
*

*

* 1. The first 1 and 2 digits indicate: the province code; 2. The 3rd and 4th digits indicate: the city code; 3. The 5th and 6th digits indicate: the district/county code;
* 4. The 7th to 14th digits indicate: the year, month, and day of birth; 5. The 15th and 16th digits indicate: the code of the local police station;
* 6. The 17th digit indicates gender: an odd number indicates a male, an even number indicates a female;
* 7. The 18th digit is the verification code: some say it is a personal information code, which is generally randomly generated by the computer and used to check the correctness of the ID card. The check code can be a number from 0 to 9, sometimes represented by x.
*

*

* The calculation method of the eighteenth digit (check code) is: 1. Multiply the 17 digits of the previous ID card number by different coefficients. The coefficients from the first to the seventeenth are: 7 9 10 5 8 4
* 2 1 6 3 7 9 10 5 8 4 2
*

*

* 2. Add the result of multiplying these 17 digits and the coefficient.
*

*

* 3. Use the addition and divide by 11 to see what the remainder is
*

* 4. The remainder can only have 11 numbers of 0 1 2 3 4 5 6 7 8 9 10. The corresponding last ID card numbers are 1 0 X 9 8 7 6 5 4 3
* 2.
*

* 5. According to the above, if the remainder is 2, the Roman numeral Ⅹ will appear on the 18th digit of the ID card. If the remainder is 10, the last digit of the ID card is 2.
*

*
* @param idcard
* @return
*/
public static boolean validate18Idcard(String idcard) {
if (idcard == null) {
return false;
}

// non-18 is false
int s=18;
if (idcard. length() != s) {
logger.error(“ID number is incorrect!”);
return false;
}
// Get the first 17 bits
String idcard17 = idcard. substring(0, 17);

// The first 17 digits are all numbers
if (!isDigital(idcard17)) {
return false;
}

String provinceid = idcard. substring(0, 2);
// check province
if (!checkProvinceid(provinceid)) {
return false;
}

// check date of birth
String birthday = idcard. substring(6, 14);

SimpleDateFormat sdf = new SimpleDateFormat(“yyyyMMdd”);

try {
Date birthDate = sdf. parse(birthday);
String tmpDate = sdf. format(birthDate);
// date of birth is incorrect
if (!tmpDate. equals(birthday)) {
return false;
}

} catch (ParseException e1) {

return false;
}

// Get the 18th bit
String idcard18Code = idcard. substring(17, 18);

char c[] = idcard17.toCharArray();

int bit[] = converCharToInt(c);

int sum17 = 0;

sum17 = getPowerSum(bit);

// Take the modulus of the sum value and 11 to get the remainder to judge the check code
String checkCode = getCheckCodeBySum(sum17);
if (null == checkCode) {
return false;
}
// Match the 18th digit of the ID card with the calculated school code, if they are not equal, it will be false
if (!idcard18Code. equalsIgnoreCase(checkCode)) {
return false;
}
//System.out.println(“Correct”);
return true;
}

/**
* Verify 15-digit ID card
*
*

     * Only check the province and date of birth
     * 

*
* @param idcard
* @return
*/
public static boolean validate15IDCard(String idcard) {
if (idcard == null) {
return false;
}
// non-15 is false
int s=15;
if (idcard. length() != s) {
return false;
}

// 15 are all numbers
if (!isDigital(idcard)) {
return false;
}

String provinceid = idcard. substring(0, 2);
// check province
if (!checkProvinceid(provinceid)) {
return false;
}

String birthday = idcard. substring(6, 12);

SimpleDateFormat sdf = new SimpleDateFormat(“yyMMdd”);

try {
Date birthDate = sdf. parse(birthday);
String tmpDate = sdf. format(birthDate);
// ID card date error
if (!tmpDate. equals(birthday)) {
return false;
}

} catch (ParseException e1) {

return false;
}

return true;
}

/**
* Convert 15-digit ID card to 18-digit ID card
*
* @param idcard
* @return
*/
public static String convertIdcarBy15bit(String idcard) {
if (idcard == null) {
return null;
}

// Non-15-digit ID card
int s=15;
if (idcard. length() != s) {
return null;
}

// 15 are all numbers
if (!isDigital(idcard)) {
return null;
}

String provinceid = idcard. substring(0, 2);
// check province
if (!checkProvinceid(provinceid)) {
return null;
}

String birthday = idcard. substring(6, 12);

SimpleDateFormat sdf = new SimpleDateFormat(“yyMMdd”);

Datebirthdate = null;
try {
birthdaydate = sdf. parse(birthday);
String tmpDate = sdf. format(birthdate);
// ID card date error
if (!tmpDate. equals(birthday)) {
return null;
}

} catch (ParseException e1) {
return null;
}

Calendar cday = Calendar. getInstance();
cday.setTime(birthdate);
String year = String. valueOf(cday. get(Calendar. YEAR));

String idcard17 = idcard.substring(0, 6) + year + idcard.substring(8);

char c[] = idcard17.toCharArray();
String checkCode = “”;

// Convert character array to integer array
int bit[] = converCharToInt(c);

int sum17 = 0;
sum17 = getPowerSum(bit);

// Obtain the sum value and take the modulus of 11 to get the remainder to check the code
checkCode = getCheckCodeBySum(sum17);

// Can’t get the check digit
if (null == checkCode) {
return null;
}
// Splice the first 17 digits with the 18th digit check code
idcard17 += checkCode;
return idcard17;
}

/**
* check province
*
* @param provinceid
* @return legally returns TRUE, otherwise returns FALSE
*/
private static boolean checkProvinceid(String provinceid) {
for (String id : cityCode) {
if (id. equals(provinceid)) {
return true;
}
}
return false;
}

/**
* Digital verification
*
* @param str
* @return
*/
private static boolean isDigital(String str) {
return str. matches(“^[0-9]*$”);
}

/**
* After multiplying each bit of the ID card with the weighting factor of the corresponding bit, the sum value is obtained
*
* @param bit
* @return
*/
private static int getPowerSum(int[] bit) {

int sum = 0;

if (power. length != bit. length) {
return sum;
}

for (int i = 0; i < bit.length; i ++ ) { for (int j = 0; j < power. length; j ++ ) { if (i == j) { sum = sum + bit[i] * power[j]; } } } return sum; } /** * Take the modulus of the sum value and 11 to get the remainder to judge the check code * * @param sum17 * @param sum17 * @return check digit */ private static String getCheckCodeBySum(int sum17) { String checkCode = null; switch (sum17 % 11) { case 10: checkCode = "2"; break; case 9: checkCode = "3"; break; case 8: checkCode = "4"; break; case 7: checkCode = "5"; break; case 6: checkCode = "6"; break; case 5: checkCode = "7"; break; case 4: checkCode = "8"; break; case 3: checkCode = "9"; break; case 2: checkCode = "x"; break; case 1: checkCode = "0"; break; case 0: checkCode = "1"; break; default: } return checkCode; } /** * Convert character array to integer array * * @param c * @return * @throws NumberFormatException */ private static int[] converCharToInt(char[] c) throws NumberFormatException { int[] a = new int[c. length]; int k = 0; for (char temp : c) { a[k++] = Integer.parseInt(String.valueOf(temp)); } return a; } public static void main(String[] args) throws Exception { String idcard15 = "130321860311519"; String idcard18 = "320902198904016033";// String idcard="610**************"; //self ID test System.out.println(isValidatedAllIdcard(idcard18)); // 15-digit ID card //System.out.println(isValidatedAllIdcard(idcard15)); // 18-digit ID card //System.out.println(isValidatedAllIdcard(idcard18)); // 15-digit ID card to 18-digit ID card //System.out.println(convertIdcarBy15bit(idcard15)); } }