[boutique] ID card operation tools

theoretical basis

410001910101123 410001 910101 123
41000119910101123X 410001 19910101 123X

15 digits: 6-digit address code + 6-digit date of birth (900101 means born on January 1, 1990) + 3-digit sequence code
Date of birth code (less than 1 and 2 digits plus 0 digits) and address code (less than 1 and 2 digits plus 0 digits) + date of birth code

  • Area code:
    1. The first and second digits indicate provinces (autonomous regions, municipalities directly under the central government and special administrative regions).
    2. The third and fourth digits indicate cities (summary codes of prefecture level cities, autonomous prefectures, leagues and municipal districts and counties directly under the central government). Among them, 01-20 and 51-70 represent provinces and municipalities directly under the central government; 21-50 refers to the region (autonomous prefecture, League).
    3. The fifth and sixth digits represent counties (municipal districts, county-level cities and banners). 01-18 refers to county-level cities under the jurisdiction of municipal districts or regions (autonomous prefectures and leagues); 21-80 indicates county (flag); 81-99 refers to county-level cities directly under the central government.
  • Sequence code:
    It refers to 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 assigned to men and the even number to women.
  • Check code
    It is calculated by the number preparation unit according to the unified formula. If a person's tail number is 0-9, there will be no X, but if the tail number is 10, then it has to be replaced by X, because if 10 is used as the tail number, the person's ID card will become 19 digits,
    The 19 digit number violates the national standard, and China's computer application system does not recognize the ID number of 19. X is the Roman numeral 10. Replacing 10 with X can ensure that citizens' ID cards meet national standards.
    The calculation method and steps of specific verification are as follows:
    1) Weighted summation of the first 17 digital body Codes:
    S = Sum(Ai * Wi), i = 0, ... , 16
    The Ai indicates the number of the ID number in the i position, and the Wi indicates the weighting factor in the i position. The corresponding values of each of them are: 79105842163 79105842
    2) Take the mold with 11 pairs of S:
    Y = mod(S, 11)
    3) The corresponding check code is obtained according to the value of module Y
    Y value 0 1 2 3 4 5 6 7 8 9 10
    Check code 1 0 X 9 8 7 6 5 4 3 2
    Where x is used instead of 10 in the Roman numeral, i.e. X.

code

public class IdCardUtil {

    /**
     * Check the eighteenth digit of the ID number.
     *
     * @param idCard
     * @return true is returned if the rule is met, otherwise false is returned
     */
    public static boolean checkLastDigit(String idCard) {
        if (idCard.length() != 18) {
            return false;
        }
        try {
            char[] charArray = idCard.toCharArray();
            //Top 17 weighting factor
            int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
            //This is the verification code corresponding to the 11 bit remainder that may be generated after dividing by 11
            String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
            int sum = 0;
            for (int i = 0; i < idCardWi.length; i++) {
                int current = Integer.parseInt(String.valueOf(charArray[i]));
                int count = current * idCardWi[i];
                sum += count;
            }
            char idCardLast = charArray[17];
            int idCardMod = sum % 11;
            if (idCardY[idCardMod].toUpperCase().equals(String.valueOf(idCardLast).toUpperCase())) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * Verify ID number
     *
     * @param idCard The ID number is 15 or 18, and the last one may be the number or letter.
     * @return true is returned for successful verification, and false is returned for failed verification
     */
    public static boolean checkIdCard(String idCard) {
        if (idCard == null || "".equals(idCard)) {
            return false;
        }
        // Define regular expressions that distinguish user ID number (15 bits or 18 bits, last bit can be letter).
        String regularExpression = "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" +
                "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)";

        boolean matches = idCard.matches(regularExpression);

        //Judge the 18th bit check value
        if (matches) {
            checkLastDigit(idCard);
        }
        return true;
    }

    /**
     * Get the birthday in the ID number, format: yyyy-MM-dd
     *
     * @param idCard
     * @return
     */
    public static String getBirth(String idCard) {
        String res = null;
        if (idCard == "" || idCard.length() != 15 && idCard.length() != 18) {
            throw new GlobalException(ResultEnum.IDCARD_ERROR);
        }
        if (idCard.length() == 15) { //410001910101123  410001 910101 123
            res = "19" + idCard.substring(6, 12);
        } else {// 41000119910101123X  410001 19910101 123X
            res = idCard.substring(6, 14);
        }
        return new StringBuffer(res).insert(4, "-").insert(7, "-").toString();
    }

    /**
     * Obtain gender
     *
     * @param idCard
     * @return true: Female false: Male
     */
    public static boolean getGender(String idCard) {
        String tmp = null;
        if (idCard == "" || idCard.length() != 15 && idCard.length() != 18) {
            throw new GlobalException(ResultEnum.IDCARD_ERROR);
        }
        if (idCard.length() == 15) { //410001910101123  410001 910101 123
            tmp = idCard.substring(11);
        } else {// 41000119910101123X  410001 19910101 123X
            tmp = idCard.substring(16);
        }
        return Integer.parseInt(tmp) % 2 == 0 ? true : false;
    }


    /**
     * Get age according to ID number.
     *
     * @param idCard
     * @return
     */
    public static int getAge(String idCard) {
        String res = null;
        if (idCard == "" || idCard.length() != 15 && idCard.length() != 18) {
            throw new GlobalException(ResultEnum.IDCARD_ERROR);
        }
        if (idCard.length() == 15) { //410001910101123  410001 910101 123
            res = "19" + idCard.substring(6, 8);
        } else {// 41000119910101123X  410001 19910101 123X
            res = idCard.substring(6, 10);
        }
        return LocalDate.now().get(ChronoField.YEAR) - Integer.parseInt(res);
    }

    /**
     * Analyze the address on the back of the ID card, obtain the villages of provinces, cities, counties and return in the form of List
     *
     * @param addr
     * @return
     * @author lin
     */
    public static List<String> splitAddr(String addr) {
        String regex = "(?<province>[^province]+province|[^Autonomous Region]+Autonomous Region|.+city)(?<city>[^autonomous prefecture]+autonomous prefecture|.+Zoning|[^city]+city|[^Alliance]+Alliance|[^region]+region)?(?<county>[^city]+city|[^county]+county|[^flag]+flag|.+area)?(?<town>[^area]+area|[^country]+country|[^town]+town|.+town)?(?<village>.*)";

        List<String> res = new ArrayList<>(5);
        Matcher m = Pattern.compile(regex).matcher(addr);
        while (m.find()) {
            String province = m.group("province");
            String city = m.group("city");
            String county = m.group("county");
            String town = m.group("town");
            String village = m.group("village");
            res.add(province);
            res.add(city);
            res.add(county);
            res.add(town);
            res.add(village);
        }
        return res;
    }

    public static void main(String[] args) {
        System.out.println(checkIdCard("41012219851810865x"));
        System.out.println(getBirth("41012219851810865x"));

        System.out.println(splitAddr("Wan Tan Xiang Wan Tan Cun, Zhongmou County, Zhengzhou City, Henan Province"));
        System.out.println(splitAddr("Shawan County, Tacheng Prefecture, Xinjiang Uygur Autonomous Region xxxx town yyyy pay"));
        System.out.println(splitAddr("Wujiaqu City, a county-level administrative division directly under the central government of Xinjiang Uygur Autonomous Region"));
        System.out.println(splitAddr("143 fuxingmennei st, Chaoyang District, Beijing"));
        System.out.println(splitAddr("Hongshan District, Wuhan City, Hubei Province"));
        System.out.println(splitAddr("Enshi City, Enshi Tujia and Miao Autonomous Prefecture, Hubei Province"));
        System.out.println(splitAddr("No. 143, Xiangyang Road, Qingzhou Development Zone, Weifang City, Shandong Province"));
        System.out.println(splitAddr("Xigaze City, Xigaze Prefecture, Tibet Autonomous Region"));
        System.out.println(splitAddr("Horqin Right Front Banner, Hinggan League, Inner Mongolia Autonomous Region"));
        System.out.println(splitAddr("Administrative divisions of Hainan province and county directly under the jurisdiction of the Zhongsha Islands and the sea area"));
        System.out.println(splitAddr("Chaoyang District, Beijing Municipality"));

        String idCard1 = "110103198810158652";
        String idCard2 = "210112198309213426";
        System.out.println(checkLastDigit(idCard1));
        System.out.println(checkLastDigit(idCard2));

        System.out.println(getBirth(idCard1));
        System.out.println(getBirth("410001910101123"));

        System.out.println(getGender(idCard1));
        System.out.println(getGender("410001910101123"));

        System.out.println(getAge(idCard1));
        System.out.println(getAge("410001910101123"));
    }
}

Keywords: JavaSE

Added by Xajel on Fri, 18 Feb 2022 14:03:33 +0200