diff --git a/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveStrategy.java b/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveStrategy.java index c822898fb..6d8671782 100644 --- a/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveStrategy.java +++ b/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveStrategy.java @@ -3,6 +3,7 @@ package org.dromara.common.sensitive.core; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.DesensitizedUtil; import lombok.AllArgsConstructor; +import org.dromara.common.sensitive.utils.DesensitizedUtils; import java.util.function.Function; @@ -80,6 +81,13 @@ public enum SensitiveStrategy { */ FIRST_MASK(DesensitizedUtil::firstMask), + /** + * 通用字符串脱敏 + * 可配置前后可见长度和中间掩码长度 + * 默认示例:前4位可见,后4位可见,中间固定4个* + */ + STRING_MASK(s -> DesensitizedUtils.mask(s, 4, 4, 4)), + /** * 清空为null */ diff --git a/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/utils/DesensitizedUtils.java b/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/utils/DesensitizedUtils.java new file mode 100644 index 000000000..8f408b2fe --- /dev/null +++ b/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/utils/DesensitizedUtils.java @@ -0,0 +1,54 @@ +package org.dromara.common.sensitive.utils; + +import cn.hutool.core.util.DesensitizedUtil; +import cn.hutool.core.util.StrUtil; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +/** + * 脱敏工具类 + * + * @author AprilWind + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class DesensitizedUtils extends DesensitizedUtil { + + /** + * 灵活脱敏方法 + * + * @param value 原始字符串 + * @param prefixVisible 前面可见长度 + * @param suffixVisible 后面可见长度 + * @param maskLength 中间掩码长度(固定显示多少 *,如果总长度不足则自动缩减) + * @return 脱敏后字符串 + */ + public static String mask(String value, int prefixVisible, int suffixVisible, int maskLength) { + if (StrUtil.isBlank(value)) { + return value; + } + + int len = value.length(); + + // 总长度小于等于前后可见长度 → 全部掩码 + if (len <= prefixVisible + suffixVisible) { + return StrUtil.repeat('*', len); + } + + // 可用长度 = 总长度 - 前后可见长度 + int available = len - prefixVisible - suffixVisible; + + // 中间掩码长度不能超过可用长度 + int actualMaskLength = Math.min(maskLength, available); + + // 剩余字符尽量显示在中间掩码旁 + int remaining = available - actualMaskLength; + String middleChars = remaining > 0 ? value.substring(prefixVisible, prefixVisible + remaining) : ""; + String middleMask = StrUtil.repeat('*', actualMaskLength); + + String prefix = value.substring(0, prefixVisible); + String suffix = value.substring(len - suffixVisible); + + return prefix + middleChars + middleMask + suffix; + } + +}