字符脱敏工具类

文章目录

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号馆
相关推荐
宸津-代码粉碎机几秒前
Spring AI企业级实战|Agent长期记忆持久化落地,彻底解决多轮对话上下文丢失问题
java·开发语言·人工智能·后端·python·spring
在放️几秒前
Python 爬虫 · bs4 模块基础
开发语言·爬虫·python
belong_my_offer2 分钟前
Python 数据采集完全指南 —— 从零开始掌握网络爬虫与文件读取
开发语言·爬虫·python
开源推荐官5 分钟前
2026 商城系统源码实测,真正适合二开的系统有哪些?
java·架构·开源
云烟成雨TD5 分钟前
Spring AI 1.x 系列【58】提示词工程(Prompt Engineering)
java·人工智能·spring
Adorable老犀牛6 分钟前
Prometheus 常用告警规则 rules.yml
开发语言·prometheus·exporter·nodeexpoeter
阿里matlab建模师11 分钟前
【机场停机位分配】matlab实现基于遗传算法的机场停机位分配优化研究
开发语言·算法·数学建模·matlab·全国大学生数学建模竞赛
總鑽風11 分钟前
[特殊字符] Spring AI Alibaba企业级智能助手落地实践
java·人工智能·spring
xiaoshuaishuai811 分钟前
C# Avalonia 依赖属性与WPF的区别
开发语言·c#·wpf
Flittly12 分钟前
【AgentScope Java新手村系列】(1)框架简介与环境搭建
java·spring boot·笔记·spring·ai