本文目录导读:

- 方法一:使用
String.replace或replaceAll(最直观) - 方法二:使用
StringBuilder或toCharArray循环替换(性能更好) - 方法三:使用正则表达式(
replaceAll配合分组) - 方法四:使用 Apache Commons Lang(
StringUtils.overlay) - 方法五:针对不同长度的身份证(15位/18位)通用处理
- 注意事项
在Java中隐藏身份证信息,常见的方法是对中间几位(通常是出生日期部分)进行脱敏(Masking),只显示前几位和后几位。
110101199001011234 -> 110101********1234 或 110101****1234。
以下是几种常用的实现方式,从简单到规范:
使用 String.replace 或 replaceAll(最直观)
这是最常用的方法,直接替换指定范围的字符为 。
public class IdCardMaskUtil {
/**
* 隐藏身份证中间部分(标准18位)
* 保留前6位和后4位,中间用8个*代替
*/
public static String maskIdCard(String idCard) {
if (idCard == null || idCard.length() != 18) {
// 如果格式不对,可以返回原值或抛出异常,这里返回原值便于演示
return idCard;
}
// 截取前6位 + 8个星号 + 后4位
return idCard.substring(0, 6) + "********" + idCard.substring(14);
}
// 测试
public static void main(String[] args) {
String id = "110101199001011234";
System.out.println(maskIdCard(id)); // 输出: 110101********1234
}
}
使用 StringBuilder 或 toCharArray 循环替换(性能更好)
如果需要更高的性能,或者需要定制脱敏规则(如对15位身份证),可以使用这种方式。
public static String maskIdCardByArray(String idCard) {
if (idCard == null || idCard.length() < 10) {
return idCard; // 过短则不处理
}
char[] chars = idCard.toCharArray();
// 隐藏从第6位(索引6)开始的连续8位(适用于18位)
// 如果长度不同,可以动态计算隐藏的起始位置和长度
int start = 6;
int end = 14; // 隐藏到第13位(索引)
// 如果身份证长度是15位,隐藏从第6位到第11位
if (idCard.length() == 15) {
start = 6;
end = 11;
}
for (int i = start; i < end; i++) {
chars[i] = '*';
}
return new String(chars);
}
使用正则表达式(replaceAll 配合分组)
利用正则分组捕获前6位和后4位,中间替换为星号。
public static String maskIdCardByRegex(String idCard) {
if (idCard == null || idCard.length() < 10) {
return idCard;
}
// 匹配前6位任意字符,中间任意字符,后4位任意字符
// $1 是前6位,$2 是后4位
return idCard.replaceAll("(\\d{6})\\d{8}(\\d{4})", "$1********$2");
// 注意:有些场景中间是8位,有些是6位,根据需求调整正则
}
使用 Apache Commons Lang(StringUtils.overlay)
如果你的项目中已经引入了 commons-lang3,可以使用它的 overlay 方法。
import org.apache.commons.lang3.StringUtils;
public static String maskIdCardByOverlay(String idCard) {
if (idCard == null || idCard.length() != 18) {
return idCard;
}
// StringUtils.overlay(str, overlay, start, end)
// 将 start 到 end 之间的字符替换为 overlay
return StringUtils.overlay(idCard, "********", 6, 14);
}
针对不同长度的身份证(15位/18位)通用处理
中国身份证有15位(旧版)和18位(新版)两种,脱敏规则略有不同(通常15位隐藏出生年月的几位)。
public static String maskGeneralIdCard(String idCard) {
if (idCard == null || idCard.length() < 10) {
return idCard;
}
int len = idCard.length();
// 至少保留前3位和后2位
int keepFront = Math.min(6, len - 4);
int keepEnd = Math.min(4, len - keepFront);
// 如果长度不足以进行有效隐藏,直接返回
if (keepFront + keepEnd >= len) {
return idCard;
}
String front = idCard.substring(0, keepFront);
String end = idCard.substring(len - keepEnd);
int maskLen = len - keepFront - keepEnd;
String mask = "*".repeat(maskLen);
return front + mask + end;
}
注意事项
- 输入校验:
idCard为null或长度异常,建议返回原值或抛出异常,而不是直接进行substring操作(会报StringIndexOutOfBoundsException)。 - 安全性:脱敏后的数据尽量不要存储到日志中(除非必要),并且避免逆向推导回原始信息。
- 显示场景:在前端展示时,通常只显示后4位(如
****1234),但在Java后端处理时,通常保留前6位和后4位,便于区分归属地。 - 国际化:如果系统处理其他国家/地区的身份证,格式不同(如美国SSN是
***-**-1234),需要单独处理。
推荐使用的方法:
- 简单直接:方法一(substring + 拼接),代码简洁,性能好。
- 灵活通用:方法五(动态长度处理),兼容15位/18位。
- 如果已有Apache Commons依赖:方法四(overlay) 可读性很好。
// 一行代码搞定(18位身份证) String masked = idCard.substring(0,6) + "********" + idCard.substring(14);