数据脱敏

。_饼干妹妹 提交于 2019-12-05 17:06:14
  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  * <p>
 37  * 脱敏序列化
 38  */
 39 @NoArgsConstructor
 40 @AllArgsConstructor
 41 public class SensitiveSerialize extends JsonSerializer<String> 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*****o@xx.com
35      */
36     EMAIL,
37     /**
38      * 银行卡, 622202************1234
39      */
40     BANK_CARD,
41     /**
42      * 密码, 永远是 ******, 与长度无关
43      */
44     PASSWORD,
45     /**
46      * 密钥, 永远是 ******, 与长度无关
47      */
48     KEY
49 
50 
51 }

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!