字符脱敏工具类

文章目录

1、字符脱敏工具类

java 复制代码
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

/**
 * 数据脱敏工具类
 *
 * @date 2024/10/30 13:44
 */

@Slf4j
public class DataDesensitizationUtils {

    public static final String STAR_1 = "*";
    public static final String STAR_2 = "**";
    public static final String STAR_3 = "***";
    public static final String STAR_4 = "****";

    /**
     * 手机号脱敏
     *
     * @param mobile 手机号
     * @return 返回值
     */
    public static String mobileDesensitize(String mobile) {
        // 如果手机号为空则返回空字符串
        if (StringUtils.isBlank(mobile)) {
            return "";
        }

        // 取手机号最后4位
        String right = StringUtils.right(mobile, 4);
        // 手机号除了最后4位都用*代替
        String leftPad = StringUtils.leftPad(right, StringUtils.length(mobile), STAR_1);
        // 移除前面默认的三位*
        String removeStart = StringUtils.removeStart(leftPad, STAR_3);
        // 取手机号前3位
        String left = StringUtils.left(mobile, 3);
        // 字符串链接并返回
        return left.concat(removeStart);
    }

    /**
     * 姓名脱敏
     *
     * @param name 姓名
     * @return 返回值
     */
    public static String nameDesensitize(String name) {
        // 名字为空则返回空字符串
        if (StringUtils.isBlank(name)) {
            return "";
        }

        // 名字长度小于等于3个字符,则将前面一个字符用*代替
        int length = 3;
        if (name.length() <= length) {
            int len = name.length() - 1;
            String right = StringUtils.right(name, len);
            return STAR_1.concat(right);
        }

        // 名字长度大于3个字符,则将前两个字符用*代替
        int len = name.length() - 2;
        String right = StringUtils.right(name, len);
        return STAR_2.concat(right);
    }

    /**
     * 地址脱敏
     *
     * @param detailAddress 地址
     * @return 返回值
     */
    public static String detailAddressDesensitize(String detailAddress) {
        int length = 10;
        String desensitizationText = STAR_4;
        // 地址为空或长度小于10个字符则默认返回*
        if (StringUtils.isBlank(detailAddress) || detailAddress.length() <= length) {
            return desensitizationText;
        } else {
            // 把地址10个字符后的所有字符替换为*
            StringBuilder address = new StringBuilder(detailAddress);
            int start = address.length() - 10;
            int end = address.length();
            return address.replace(start, end, desensitizationText).toString();
        }
    }

	/**
     * 对指定字符串的部分内容进行脱敏处理,替换为指定数量的星号。
     *
     * @param start       需要脱敏的起始位置(包含)
     * @param end         需要脱敏的结束位置(不包含)
     * @param content     原始字符串
     * @param maxStarSize 最大星号数量,超出部分将被截断
     * @return 处理后的字符串
     */
    public static String contentDesensitize(int start, int end, String content, int maxStarSize) {
        // 字符串为空则返回空字符串
        if (StringUtils.isBlank(content)) {
            return "";
        }

        // 起始位置不能小于0
        start = Math.max(0, start);
        // 结束位置不能大于字符串最大长度
        end = Math.min(content.length(), end);

        // 如果结束位置小于起始位置或者结束位置大于原始串长度,则返回原始串。
        if (end < start) {
            return content;
        }

        // 取两者最小值,即中间最多出现maxStarSize个*号
        int min = Math.min(end - start, maxStarSize);
        // 取两者最大值作为重复次数,即保证*号重复次数不为负数
        int count = Math.max(0, min);
        // 计算count次数的*号字符串,repeat是JDK11+提供的方法
        // JDK8可以使用以下方法 
        // String repeat = StringUtils.repeat(STAR_1, count);
        String repeat = STAR_1.repeat(count);
        // 将字符串start与end中间的明文替换为*号
        return new StringBuilder(content)
                .replace(start, end, repeat)
                .toString();
    }

    /**
     * 对指定字符串的部分内容进行脱敏处理,替换为指定数量的星号。
     *
     * @param start   需要脱敏的起始位置(包含)
     * @param end     需要脱敏的结束位置(不包含)
     * @param content 原始字符串
     * @return 处理后的字符串
     */
    public static String contentDesensitize(int start, int end, String content) {
        // 默认最大*号数量即中间替换字符数量
        return contentDesensitize(start, end, content, end - start);
    }

}

2、测试工具类

java 复制代码
@Slf4j
@ExtendWith(MockitoExtension.class)
public class DataDesensitizationUtilsTest {

    @Test
    public void testMobileDesensitize() {
        String mobile = "13011112222";
        String result = DataDesensitizationUtils.mobileDesensitize(mobile);
        log.info("手机号脱敏结果:{}", result);
    }

    @Test
    public void testNameDesensitize() {
        String name = "诸葛孔明";
        String result = DataDesensitizationUtils.nameDesensitize(name);
        log.info("姓名脱敏结果:{}", result);
    }

    @Test
    public void testAddressDesensitize() {
        String address = "北京首钢国际会展中心9号馆、10号馆";
        String result = DataDesensitizationUtils.detailAddressDesensitize(address);
        log.info("地址脱敏结果:{}", result);
    }

	@Test
    public void testStringUtils() {
        String param = "北京首钢国际会展中心9号馆、10号馆";
        String result1 = StringUtils.left(param, 3);
        log.info("处理结果1:{}", result1);

        String result2 = StringUtils.right(param, 4);
        log.info("处理结果2:{}", result2);

        String result3 = StringUtils.leftPad(result2, param.length(), "*");
        log.info("处理结果3:{}", result3);
    }
    
	@Test
    public void testContentDesensitize() {
        String param = "诸葛孔明";
        String result1 = DataDesensitizationUtils.contentDesensitize(1, 7, param);
        log.info("处理结果1:{}", result1);
        String result2 = DataDesensitizationUtils.contentDesensitize(1, param.length() - 7, param, 6);
        log.info("处理结果2:{}", result2);
        String result3 = DataDesensitizationUtils.contentDesensitize(0, param.length() + 7, param, 6);
        log.info("处理结果3:{}", result3);
    }

}

3、测试结果:

log 复制代码
2024-10-31 09:36:11 [INFO ] [main] - [] - com.summer.toolkit.service.DataDesensitizationUtilsTest.testNameDesensitize():30 - 姓名脱敏结果:**孔明
2024-10-31 09:36:11 [INFO ] [main] - [] - com.summer.toolkit.service.DataDesensitizationUtilsTest.testMobileDesensitize():23 - 手机号脱敏结果:130****2222
2024-10-31 09:36:11 [INFO ] [main] - [] - com.summer.toolkit.service.DataDesensitizationUtilsTest.testAddressDesensitize():37 - 地址脱敏结果:北京首钢国际会展****
2024-10-31 09:36:11 [INFO ] [main] - [] - com.summer.toolkit.service.DataDesensitizationUtilsTest.testStringUtils():44 - 处理结果1:北京首
2024-10-31 09:36:11 [INFO ] [main] - [] - com.summer.toolkit.service.DataDesensitizationUtilsTest.testStringUtils():47 - 处理结果2:10号馆
2024-10-31 09:36:11 [INFO ] [main] - [] - com.summer.toolkit.service.DataDesensitizationUtilsTest.testStringUtils():50 - 处理结果3:**************10号馆
相关推荐
浮游本尊2 分钟前
Java学习第22天 - 云原生与容器化
java
渣哥2 小时前
原来 Java 里线程安全集合有这么多种
java
间彧2 小时前
Spring Boot集成Spring Security完整指南
java
间彧2 小时前
Spring Secutiy基本原理及工作流程
java
Java水解3 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
洛小豆5 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学6 小时前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端
ytadpole6 小时前
Spring Cloud Gateway:一次不规范 URL 引发的路由转发404问题排查
java·后端
华仔啊6 小时前
基于 RuoYi-Vue 轻松实现单用户登录功能,亲测有效
java·vue.js·后端