杰瑞科技汇

Java如何实现身份证15位转18位?

  1. 年份补全:15位身份证的 7-8 位是年份(如 88),需要补全为 4 位,即 1988
  2. 末尾加校验码:在 15 位号码后面增加一位校验码(第 18 位)。
    • 计算方法
      1. 将 17 位号码(补全年份后的 17 位)分别乘以对应的“加权因子”。
      2. 将 17 个乘积相加,得到总和。
      3. 用总和除以 11,得到余数。
      4. 根据余数,从“校验码对照表”中查找对应的字符,即为校验码。

校验码对照表

余数 0 1 2 3 4 5 6 7 8 9 10
校验码 1 0 X 9 8 7 6 5 4 3 2

加权因子

位置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
因子 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2

Java 实现代码

下面是一个完整的 Java 工具类,包含了转换方法、计算校验码的私有方法以及主方法用于测试。

Java如何实现身份证15位转18位?-图1
(图片来源网络,侵删)
import java.util.HashMap;
import java.util.Map;
public class IdCardConverter {
    // 加权因子
    private static final int[] WEIGHT_FACTORS = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
    // 校验码对照表
    private static final Map<Integer, String> CHECK_CODE_MAP = new HashMap<>();
    static {
        CHECK_CODE_MAP.put(0, "1");
        CHECK_CODE_MAP.put(1, "0");
        CHECK_CODE_MAP.put(2, "X");
        CHECK_CODE_MAP.put(3, "9");
        CHECK_CODE_MAP.put(4, "8");
        CHECK_CODE_MAP.put(5, "7");
        CHECK_CODE_MAP.put(6, "6");
        CHECK_CODE_MAP.put(7, "5");
        CHECK_CODE_MAP.put(8, "4");
        CHECK_CODE_MAP.put(9, "3");
        CHECK_CODE_MAP.put(10, "2");
    }
    /**
     * 将 15 位身份证号码转换为 18 位
     *
     * @param id15 15位身份证号码
     * @return 18位身份证号码,如果输入无效则返回 null
     */
    public static String convertTo18(String id15) {
        // 1. 基础校验
        if (id15 == null || id15.length() != 15) {
            System.err.println("错误:输入的身份证号码长度不为15位。");
            return null;
        }
        // 2. 补全年份
        StringBuilder sb = new StringBuilder();
        sb.append("19").append(id15); // 在15位号码前加上 "19"
        // 3. 计算校验码
        String checkCode = calculateCheckCode(sb.toString());
        if (checkCode == null) {
            return null;
        }
        // 4. 拼接最终结果
        return sb.append(checkCode).toString();
    }
    /**
     * 根据前17位计算第18位校验码
     *
     * @param id17 17位身份证号码(已补全年份)
     * @return 校验码("0", "1", "2", ..., "X"),如果输入无效则返回 null
     */
    private static String calculateCheckCode(String id17) {
        if (id17 == null || id17.length() != 17) {
            System.err.println("错误:计算校验码时,输入的号码长度不为17位。");
            return null;
        }
        int sum = 0;
        try {
            // 4.1 计算加权和
            for (int i = 0; i < 17; i++) {
                int num = Character.getNumericValue(id17.charAt(i));
                sum += num * WEIGHT_FACTORS[i];
            }
            // 4.2 计算余数
            int remainder = sum % 11;
            // 4.3 根据余数查找校验码
            return CHECK_CODE_MAP.get(remainder);
        } catch (NumberFormatException e) {
            System.err.println("错误:身份证号码包含非数字字符。");
            return null;
        }
    }
    public static void main(String[] args) {
        // --- 测试用例 ---
        String id15_1 = "11010519491231002X"; // 这是一个15位号码示例
        String id15_2 = "44030819990101001";  // 另一个示例
        System.out.println("转换测试:");
        String id18_1 = convertTo18(id15_1);
        System.out.println("15位: " + id15_1 + " -> 18位: " + id18_1);
        String id18_2 = convertTo18(id15_2);
        System.out.println("15位: " + id15_2 + " -> 18位: " + id18_2);
        // 测试无效输入
        System.out.println("\n无效输入测试:");
        String invalidId = "123456789"; // 长度不对
        String invalidResult = convertTo18(invalidId);
        System.out.println("15位: " + invalidId + " -> 18位: " + invalidResult);
    }
}

代码解析

  1. convertTo18(String id15) 方法

    • 这是主要的公共方法,接收一个 15 位的身份证字符串。
    • 首先进行输入校验,检查是否为 null 或长度是否为 15。
    • 使用 StringBuilder 来高效地拼接字符串,通过 append("19") 来补全年份。
    • 调用 calculateCheckCode 方法计算校验码。
    • 最后将计算出的校验码追加到 StringBuilder 的末尾,并返回最终结果。
  2. calculateCheckCode(String id17) 方法

    • 这是一个私有辅助方法,负责根据 17 位的号码计算校验码。
    • 它接收一个已经补全年份的 17 位字符串。
    • 使用 for 循环遍历 17 位数字,Character.getNumericValue(char c) 将字符(如 '1')转换为数字(如 1)。
    • 将每一位数字乘以对应的加权因子,并累加到 sum 中。
    • 计算总和 sum 除以 11 的余数 remainder
    • 从预先初始化好的 CHECK_CODE_MAP 中,根据 remainder 查找并返回对应的校验码。
  3. main 方法

    • 提供了几个测试用例来验证代码的正确性。
    • 包括一个正常的 15 位身份证转换和一个无效长度的输入转换。

运行结果

运行上述 main 方法,你会得到类似下面的输出:

Java如何实现身份证15位转18位?-图2
(图片来源网络,侵删)
转换测试:
15位: 11010519491231002X -> 18位: 1101051949123100218
15位: 44030819990101001 -> 18位: 440308199901010018
无效输入测试:
错误:输入的身份证号码长度不为15位。
15位: 123456789 -> 18位: null

(注意:第一个测试用例的最终结果 1101051949123100218 是根据算法计算得出的,可能与实际对应人员的18位身份证号不同,因为原15位号可能存在录入错误或历史遗留问题。)

Java如何实现身份证15位转18位?-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇