数据脱敏

  1 import cn.hutool.core.util.StrUtil;
  2 
  3 /**
  4  * 脱敏工具类
  5  **/
  6 public class DesensitizedUtils {
  7 
  8     /**
  9      * 对字符串进行脱敏操作
 10      *
 11      * @param origin          原始字符串
 12      * @param prefixNoMaskLen 左侧需要保留几位明文字段
 13      * @param suffixNoMaskLen 右侧需要保留几位明文字段
 14      * @param maskStr         用于遮罩的字符串, 如'*'
 15      * @return 脱敏后结果
 16      */
 17     public static String desValue(String origin, int prefixNoMaskLen, int suffixNoMaskLen, String maskStr) {
 18         if (origin == null) {
 19             return null;
 20         }
 21 
 22         StringBuilder sb = new StringBuilder();
 23         for (int i = 0, n = origin.length(); i < n; i++) {
 24             if (i < prefixNoMaskLen) {
 25                 sb.append(origin.charAt(i));
 26                 continue;
 27             }
 28             if (i > (n - suffixNoMaskLen - 1)) {
 29                 sb.append(origin.charAt(i));
 30                 continue;
 31             }
 32             sb.append(maskStr);
 33         }
 34         return sb.toString();
 35     }
 36 
 37     /**
 38      * 【中文姓名】只显示最后一个汉字,其他隐藏为星号,比如:**梦
 39      *
 40      * @param fullName 姓名
 41      * @return 结果
 42      */
 43     public static String chineseName(String fullName) {
 44         if (fullName == null) {
 45             return null;
 46         }
 47         return desValue(fullName, 0, 1, "*");
 48     }
 49 
 50     /**
 51      * 【身份证号】显示前六位, 四位,其他隐藏。共计18位或者15位,比如:340304*******1234
 52      *
 53      * @param id 身份证号码
 54      * @return 结果
 55      */
 56     public static String idCardNum(String id) {
 57         return desValue(id, 6, 4, "*");
 58     }
 59 
 60     /**
 61      * 【固定电话】后四位,其他隐藏,比如 ****1234
 62      *
 63      * @param num 固定电话
 64      * @return 结果
 65      */
 66     public static String fixedPhone(String num) {
 67         return desValue(num, 0, 4, "*");
 68     }
 69 
 70     /**
 71      * 【手机号码】前三位,后四位,其他隐藏,比如135****6810
 72      *
 73      * @param num 手机号码
 74      * @return 结果
 75      */
 76     public static String mobilePhone(String num) {
 77         return desValue(num, 3, 4, "*");
 78     }
 79 
 80     /**
 81      * 【地址】只显示到地区,不显示详细地址,比如:北京市海淀区****
 82      *
 83      * @param address 地址
 84      * @return 结果
 85      */
 86     public static String address(String address) {
 87         return desValue(address, 6, 0, "*");
 88     }
 89 
 90     /**
 91      * 【电子邮箱 邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示,比如:d**@126.com
 92      *
 93      * @param email 电子邮箱
 94      * @return 结果
 95      */
 96     public static String email(String email) {
 97         if (email == null) {
 98             return null;
 99         }
100         int index = StrUtil.indexOf(email, '@');
101         if (index <= 1) {
102             return email;
103         }
104         String preEmail = desValue(email.substring(0, index), 1, 0, "*");
105         return preEmail + email.substring(index);
106 
107     }
108 
109     /**
110      * 【银行卡号】前六位,后四位,其他用星号隐藏每位1个星号,比如:622260**********1234
111      *
112      * @param cardNum 银行卡号
113      * @return 结果
114      */
115     public static String bankCard(String cardNum) {
116         return desValue(cardNum, 6, 4, "*");
117     }
118 
119     /**
120      * 【密码】密码的全部字符都用*代替,比如:******
121      *
122      * @param password 密码
123      * @return 结果
124      */
125     public static String password(String password) {
126         if (password == null) {
127             return null;
128         }
129         return "******";
130     }
131 
132     /**
133      * 【密钥】密钥除了最后三位,全部都用*代替,比如:***xdS
134      * 脱敏后长度为6,如果明文长度不足三位,则按实际长度显示,剩余位置补*
135      *
136      * @param key 密钥
137      * @return 结果
138      */
139     public static String key(String key) {
140         if (key == null) {
141             return null;
142         }
143         int viewLength = 6;
144         StringBuilder tmpKey = new StringBuilder(desValue(key, 0, 3, "*"));
145         if (tmpKey.length() > viewLength) {
146             return tmpKey.substring(tmpKey.length() - viewLength);
147         } else if (tmpKey.length() < viewLength) {
148             int buffLength = viewLength - tmpKey.length();
149             for (int i = 0; i < buffLength; i++) {
150                 tmpKey.insert(0, "*");
151             }
152             return tmpKey.toString();
153         } else {
154             return tmpKey.toString();
155         }
156     }
157 
158 }
 1 /**
 2  * 对象脱敏注解
 3  *
 4  * @author mayee
 5  * @version v1.0
 6  **/
 7 @Retention(RetentionPolicy.RUNTIME)
 8 @Target(ElementType.FIELD)
 9 @JacksonAnnotationsInside
10 @JsonSerialize(using = SensitiveSerialize.class)
11 public @interface Sensitive {
12 
13     /**
14      * 脱敏数据类型, 非Customer时, 将忽略 refixNoMaskLen 和 suffixNoMaskLen 和 maskStr
15      */
16     SensitiveTypeEnum type() default SensitiveTypeEnum.CUSTOMER;
17 
18     /**
19      * 前置不需要打码的长度
20      */
21     int prefixNoMaskLen() default 0;
22 
23     /**
24      * 后置不需要打码的长度
25      */
26     int suffixNoMaskLen() default 0;
27 
28     /**
29      * 用什么打码
30      */
31     String maskStr() default "*";
32 
33 }
 32 
 33 /**
 34  * @author lengleng
 35  * @date 2019-08-13
 36  * 

37 * 脱敏序列化 38 */ 39 @NoArgsConstructor 40 @AllArgsConstructor 41 public class SensitiveSerialize extends JsonSerializer implements ContextualSerializer { 42 43 private SensitiveTypeEnum type; 44 private Integer prefixNoMaskLen; 45 private Integer suffixNoMaskLen; 46 private String maskStr; 47 48 @Override 49 public void serialize(final String origin, final JsonGenerator jsonGenerator, 50 final SerializerProvider serializerProvider) throws IOException { 51 switch (type) { 52 case CHINESE_NAME: 53 jsonGenerator.writeString(DesensitizedUtils.chineseName(origin)); 54 break; 55 case ID_CARD: 56 jsonGenerator.writeString(DesensitizedUtils.idCardNum(origin)); 57 break; 58 case FIXED_PHONE: 59 jsonGenerator.writeString(DesensitizedUtils.fixedPhone(origin)); 60 break; 61 case MOBILE_PHONE: 62 jsonGenerator.writeString(DesensitizedUtils.mobilePhone(origin)); 63 break; 64 case ADDRESS: 65 jsonGenerator.writeString(DesensitizedUtils.address(origin)); 66 break; 67 case EMAIL: 68 jsonGenerator.writeString(DesensitizedUtils.email(origin)); 69 break; 70 case BANK_CARD: 71 jsonGenerator.writeString(DesensitizedUtils.bankCard(origin)); 72 break; 73 case PASSWORD: 74 jsonGenerator.writeString(DesensitizedUtils.password(origin)); 75 break; 76 case KEY: 77 jsonGenerator.writeString(DesensitizedUtils.key(origin)); 78 break; 79 case CUSTOMER: 80 jsonGenerator.writeString(DesensitizedUtils.desValue(origin, prefixNoMaskLen, suffixNoMaskLen, maskStr)); 81 break; 82 default: 83 throw new IllegalArgumentException("Unknow sensitive type enum " + type); 84 } 85 } 86 87 @Override 88 public JsonSerializer createContextual(final SerializerProvider serializerProvider, 89 final BeanProperty beanProperty) throws JsonMappingException { 90 if (beanProperty != null) { 91 if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) { 92 Sensitive sensitive = beanProperty.getAnnotation(Sensitive.class); 93 if (sensitive == null) { 94 sensitive = beanProperty.getContextAnnotation(Sensitive.class); 95 } 96 if (sensitive != null) { 97 return new SensitiveSerialize(sensitive.type(), sensitive.prefixNoMaskLen(), sensitive.suffixNoMaskLen(), sensitive.maskStr()); 98 } 99 } 100 return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty); 101 } 102 return serializerProvider.findNullValueSerializer(null); 103 } 104 }

 1 /**
 2  * 敏感信息枚举类
 3  *
 4  * @author mayee
 5  * @version v1.0
 6  **/
 7 public enum SensitiveTypeEnum {
 8 
 9     /**
10      * 自定义
11      */
12     CUSTOMER,
13     /**
14      * 用户名, 刘*华, 徐*
15      */
16     CHINESE_NAME,
17     /**
18      * 身份证号, 110110********1234
19      */
20     ID_CARD,
21     /**
22      * 座机号, ****1234
23      */
24     FIXED_PHONE,
25     /**
26      * 手机号, 176****1234
27      */
28     MOBILE_PHONE,
29     /**
30      * 地址, 北京********
31      */
32     ADDRESS,
33     /**
34      * 电子邮件, s*****[email protected]
35      */
36     EMAIL,
37     /**
38      * 银行卡, 622202************1234
39      */
40     BANK_CARD,
41     /**
42      * 密码, 永远是 ******, 与长度无关
43      */
44     PASSWORD,
45     /**
46      * 密钥, 永远是 ******, 与长度无关
47      */
48     KEY
49 
50 
51 }

 

你可能感兴趣的:(数据脱敏)