掩碼處理--方法二
阿新 • • 發佈:2018-11-10
x 649 1package com.foresee.zxpt.common.mask; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializerFeature; import com.google.gson.Gson; import lombok.extern.slf4j.Slf4j; /** * 資料脫敏處理工具類 * @version 1.0 * @date 2018年9月18日下午5:23:05 */ @Slf4j public class SensitiveInfoUtils { /** * 中文名 */ public static final String CHINESE_NAME="01"; /** * 身份證號 */ public static final String ID_CARD="02"; /** * 座機號 */ public static final String TELE_PHONE="03"; /** * 固定電話 */ public static final String FIXED_PHONE="04"; /** * 手機號 */ public static final String MOBILE_PHONE="05"; /** * 電話號碼(包括手機號和固定電話) */ public static final String PHONE="06"; /** * 地址 */ public static final String ADDRESS="07"; /** * 電子郵件 */ public static final String EMAIL="08"; /** * 銀行卡 */ public static final String BANK_CARD="09"; /** * 公司開戶銀行聯號 */ public static final String CNAPS_CODE="10"; /** * 車輛識別號 */ public static final String CAR_CODE="11"; /** * 房源編號\土地稅源編號\土地使用證編號 */ public static final String RESOURCE_CODE="12"; /** * 車牌號 */ public static final String PLATE_NUMBER="13"; /** * [中文姓名] 只顯示第一個漢字,其他隱藏為2個星號<例子:李**> * * @param name * @return */ public static String chineseName(String fullName) { if (StringUtils.isBlank(fullName)) { return ""; } String name = StringUtils.left(fullName, 1); return StringUtils.rightPad(name, StringUtils.length(fullName), "*"); } /** * [中文姓名] 只顯示第一個漢字,其他隱藏為2個星號<例子:李**> * * @param familyName * @param givenName * @return */ public static String chineseName(String familyName, String givenName) { if (StringUtils.isBlank(familyName) || StringUtils.isBlank(givenName)) { return ""; } return chineseName(familyName + givenName); } /** * [身份證號] 顯示前6後2,其他隱藏。共計18位或者15位。<例子:*************5762> * * @param id * @return */ public static String idCardNum(String id) { if (StringUtils.isBlank(id)) { return ""; } return StringUtils.left(id, 6).concat(StringUtils .removeStart(StringUtils.leftPad(StringUtils.right(id, 2), StringUtils.length(id), "*"), "******")); } /** * [固定電話] 後四位,其他隱藏<例子:****1234> * * @param num * @return */ public static String telePhone(String num) { if (StringUtils.isBlank(num)) { return ""; } return StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*"); } /** * [固定電話] 前兩位,後兩位,其他隱藏<例子:88**34> * * @param num * @return */ public static String fixedPhone(String num) { if (StringUtils.isBlank(num)) { return ""; } return StringUtils.left(num, 2).concat(StringUtils .removeStart(StringUtils.leftPad(StringUtils.right(num, 2), StringUtils.length(num), "*"), "**")); } /** * [手機號碼] 前三位,後四位,其他隱藏<例子:138******1234> * * @param num * @return */ public static String mobilePhone(String num) { if (StringUtils.isBlank(num)) { return ""; } return StringUtils.left(num, 3).concat(StringUtils .removeStart(StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*"), "***")); } /** * [電話號碼] 以/分開 前三位,後四位,其他隱藏<例子:138******1234/****1234> * * @param num * @return */ public static String phone(String num) { if (StringUtils.isBlank(num)) { return ""; } String[] split = num.split("/"); StringBuffer sb = new StringBuffer(); if (split.length > 1) { for (String number : split) { number = number.trim(); number = caseNum(number); sb.append(number).append("/"); } num = sb.toString(); if (num.endsWith("/")) { num = num.substring(0, num.length() - 1); } } else { num = num.trim(); num = caseNum(num); } return num; } private static String caseNum(String num) { switch (num.length()) { case 7: num = fixedPhone(num); break; case 8: num = fixedPhone(num); break; case 11: num = mobilePhone(num); break; default: break; } return num; } /** * 資料長度大於12位,只顯示前面sensitiveSize位<例子:北京市海淀區****> * * @param address * @param sensitiveSize * 敏感資訊長度 * @return */ private static String code_left(String address, int sensitiveSize) { if (StringUtils.isBlank(address)) { return ""; } address=address.trim(); return StringUtils.rightPad(StringUtils.left(address, sensitiveSize), StringUtils.length(address), "*"); } /** * 資料長度小於於12位,從後往前數sensitiveSize位設定為*<例子:廣州市******> * * @param address * @param sensitiveSize * 敏感資訊長度 * @return */ private static String code_right_hide(String address, int sensitiveSize) { if (StringUtils.isBlank(address)) { return ""; } int length = StringUtils.length(address); return StringUtils.rightPad(StringUtils.left(address, length - sensitiveSize), length, "*"); } /** * 資料從後往前數sensitiveSize顯示<例子:***廣州市天河區> * * @param address * @param sensitiveSize * @return */ @SuppressWarnings("unused") private static String code_right_display(String address, int sensitiveSize) { if (StringUtils.isBlank(address)) { return ""; } String num = StringUtils.right(address, sensitiveSize); return StringUtils.leftPad(num, StringUtils.length(address), "*"); } /** * [地址] 如長度大於等於12位,留前6位,其餘為*,如少於12位,從後往前掩蓋6位為* * * @param address * @param sensitiveSize * 敏感資訊長度 * @return */ public static String address(String address) { if (StringUtils.isBlank(address)) { return ""; } int length = StringUtils.length(address); if (length >= 12) { return code_left(address, 6); } else { return code_right_hide(address, 6); } } /** * [電子郵箱] 郵箱字首僅顯示第一個字母,字首其他隱藏,用星號代替,@及後面的地址顯示<例子:g**@163.com> * * @param email * @return */ public static String email(String email) { if (StringUtils.isBlank(email)) { return ""; } int index = StringUtils.indexOf(email, "@"); if (index <= 1) return email; else return StringUtils.rightPad(StringUtils.left(email, 1), index, "*") .concat(StringUtils.mid(email, index, StringUtils.length(email))); } /** * [銀行卡號] 前六位,後四位,其他用星號隱藏每位1個星號<例子:6222600**********1234> * * @param cardNum * @return */ public static String bankCard(String cardNum) { if (StringUtils.isBlank(cardNum)) { return ""; } return StringUtils.left(cardNum, 6).concat(StringUtils.removeStart( StringUtils.leftPad(StringUtils.right(cardNum, 4), StringUtils.length(cardNum), "*"), "******")); } /** * [公司開戶銀行聯號] 公司開戶銀行聯行號,顯示前兩位,其他用星號隱藏,每位1個星號<例子:12********> * * @param code * @return */ public static String cnapsCode(String code) { if (StringUtils.isBlank(code)) { return ""; } return StringUtils.rightPad(StringUtils.left(code, 2), StringUtils.length(code), "*"); } /** * [車牌號] 車牌號,顯示前4位,其他用星號隱藏,每位1個星號<例子:1222***> * * @param code * @return */ public static String plateNumber(String code) { if (StringUtils.isBlank(code)) { return ""; } return StringUtils.rightPad(StringUtils.left(code, 4), StringUtils.length(code), "*"); } /** * [車輛識別號] 車輛識別號,從後往前數8位設定為*,其他用星號隱藏,每位1個星號<例子:1222********> * * @param code * @return */ public static String carCode(String code) { if (StringUtils.isBlank(code)) { return ""; } return code_right_hide(code, 8); } /** * [ 房源編號\土地稅源編號\土地使用證編號] 房源編號,留開頭3位,其餘為*<例子:122***> * * @param code * @return */ public static String resourceCode(String code) { if (StringUtils.isBlank(code)) { return ""; } return StringUtils.rightPad(StringUtils.left(code, 3), StringUtils.length(code), "*"); } /** * 字串反轉 * * @param s * @return */ @SuppressWarnings("unused") private static String reverseStringBuilder(String s) { StringBuilder sb = new StringBuilder(s); String afterreverse = sb.reverse().toString(); return afterreverse; } /** * 獲取脫敏json串 <注意:遞迴引用會導致java.lang.StackOverflowError> * * @param javaBean * @return */ public static String getJson(Object javaBean) { String json = null; if (null != javaBean) { Class<? extends Object> raw = javaBean.getClass(); try { if (raw.isInterface()) return json; Gson g = new Gson(); Object clone = g.fromJson(g.toJson(javaBean, javaBean.getClass()), javaBean.getClass()); Set<Integer> referenceCounter = new HashSet<Integer>(); SensitiveInfoUtils.replace(SensitiveInfoUtils.findAllField(raw), clone, referenceCounter); json = JSON.toJSONString(clone, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty); referenceCounter.clear(); referenceCounter = null; } catch (Throwable e) { log.error("SensitiveInfoUtils.getJson() ERROR", e); } } return json; } private static Field[] findAllField(Class<?> clazz) { Field[] fileds = clazz.getDeclaredFields(); while (null != clazz.getSuperclass() && !Object.class.equals(clazz.getSuperclass())) { fileds = (Field[]) ArrayUtils.addAll(fileds, clazz.getSuperclass().getDeclaredFields()); clazz = clazz.getSuperclass(); } return fileds; } private static void replace(Field[] fields, Object javaBean, Set<Integer> referenceCounter) throws IllegalArgumentException, IllegalAccessException { if (null != fields && fields.length > 0) { for (Field field : fields) { field.setAccessible(true); if (null != field && null != javaBean) { Object value = field.get(javaBean); if (null != value) { Class<?> type = value.getClass(); // 1.處理子屬性,包括集合中的 if (type.isArray()) { int len = Array.getLength(value); for (int i = 0; i < len; i++) { Object arrayObject = Array.get(value, i); SensitiveInfoUtils.replace(SensitiveInfoUtils.findAllField(arrayObject.getClass()), arrayObject, referenceCounter); } } else if (value instanceof Collection<?>) { Collection<?> c = (Collection<?>) value; Iterator<?> it = c.iterator(); while (it.hasNext()) { Object collectionObj = it.next(); SensitiveInfoUtils.replace(SensitiveInfoUtils.findAllField(collectionObj.getClass()), collectionObj, referenceCounter); } } else if (value instanceof Map<?, ?>) { Map<?, ?> m = (Map<?, ?>) value; Set<?> set = m.entrySet(); for (Object o : set) { Entry<?, ?> entry = (Entry<?, ?>) o; Object mapVal = entry.getValue(); SensitiveInfoUtils.replace(SensitiveInfoUtils.findAllField(mapVal.getClass()), mapVal, referenceCounter); } } else if (!type.isPrimitive() && !StringUtils.startsWith(type.getPackage().getName(), "javax.") && !StringUtils.startsWith(type.getPackage().getName(), "java.") && !StringUtils.startsWith(field.getType().getName(), "javax.") && !StringUtils.startsWith(field.getName(), "java.") && referenceCounter.add(value.hashCode())) { SensitiveInfoUtils.replace(SensitiveInfoUtils.findAllField(type), value, referenceCounter); } } // 2. 處理自身的屬性 SensitiveInfo annotation = field.getAnnotation(SensitiveInfo.class); if (field.getType().equals(String.class) && null != annotation) { String valueStr = (String) value; if (StringUtils.isNotBlank(valueStr)) { switch (annotation.type()) { case CHINESE_NAME: { field.set(javaBean, SensitiveInfoUtils.chineseName(valueStr)); break; } case ID_CARD: { field.set(javaBean, SensitiveInfoUtils.idCardNum(valueStr)); break; } case TELE_PHONE: { field.set(javaBean, SensitiveInfoUtils.telePhone(valueStr)); break; } case FIXED_PHONE: { field.set(javaBean, SensitiveInfoUtils.fixedPhone(valueStr)); break; } case MOBILE_PHONE: { field.set(javaBean, SensitiveInfoUtils.mobilePhone(valueStr)); break; } case PHONE: { field.set(javaBean, SensitiveInfoUtils.phone(valueStr)); break; } case ADDRESS: { field.set(javaBean, SensitiveInfoUtils.address(valueStr)); break; } case EMAIL: { field.set(javaBean, SensitiveInfoUtils.email(valueStr)); break; } case BANK_CARD: { field.set(javaBean, SensitiveInfoUtils.bankCard(valueStr)); break; } case CNAPS_CODE: { field.set(javaBean, SensitiveInfoUtils.cnapsCode(valueStr)); break; } case PLATE_NUMBER: { field.set(javaBean, SensitiveInfoUtils.plateNumber(valueStr)); break; } case CAR_CODE: { field.set(javaBean, SensitiveInfoUtils.carCode(valueStr)); break; } case RESOURCE_CODE: { field.set(javaBean, SensitiveInfoUtils.resourceCode(valueStr)); break; } } } } } } } } public static String mask(String code,String type){ if (StringUtils.isNotBlank(code)&&StringUtils.isNotBlank(type)) { code = code.trim(); switch (type) { case CHINESE_NAME: { code = SensitiveInfoUtils.chineseName(code); break; } case ID_CARD: { code = SensitiveInfoUtils.idCardNum(code); break; } case TELE_PHONE: { code = SensitiveInfoUtils.telePhone(code); break; } case FIXED_PHONE: { code =SensitiveInfoUtils.fixedPhone(code); break; } case MOBILE_PHONE: { code = SensitiveInfoUtils.mobilePhone(code); break; } case PHONE: { code = SensitiveInfoUtils.phone(code); break; } case ADDRESS: { code = SensitiveInfoUtils.address(code); break; } case EMAIL: { code =SensitiveInfoUtils.email(code); break; } case BANK_CARD: { code =SensitiveInfoUtils.bankCard(code); break; } case CNAPS_CODE: { code =SensitiveInfoUtils.cnapsCode(code); break; } case PLATE_NUMBER: { code = SensitiveInfoUtils.plateNumber(code); break; } case CAR_CODE: { code =SensitiveInfoUtils.carCode(code); break; } case RESOURCE_CODE: { code =SensitiveInfoUtils.resourceCode(code); break; } } } return code; } // ---------------------------------------------------------------------------------------------- public static Method[] findAllMethod(Class<?> clazz) { Method[] methods = clazz.getMethods(); return methods; } // ---------------------------------------------------------------------------------------------- public static enum SensitiveType { /** * 中文名 */ CHINESE_NAME, /** * 身份證號 */ ID_CARD, /** * 座機號 */ TELE_PHONE, /** * 固定電話 */ FIXED_PHONE, /** * 手機號 */ MOBILE_PHONE, /** * 電話號碼(包括手機號和固定電話) */ PHONE, /** * 地址 */ ADDRESS, /** * 電子郵件 */ EMAIL, /** * 銀行卡 */ BANK_CARD, /** * 公司開戶銀行聯號 */ CNAPS_CODE, /** * 車輛識別號 */ CAR_CODE, /** * 房源編號\土地稅源編號\土地使用證編號 */ RESOURCE_CODE, /** * 車牌號 */ PLATE_NUMBER; } }
package com.foresee.zxpt.common.mask;
2
3
import java.lang.reflect.Array;
4
import java.lang.reflect.Field;
5
import java.lang.reflect.Method;
6
import java.util.Collection;
7
import java.util.HashSet;
8
import java.util.Iterator;
9
import java.util.Map;
10
import java.util.Map.Entry;
11
import java.util.Set;
12
13
import org.apache.commons.lang3.ArrayUtils;
14
import org.apache.commons.lang3.StringUtils;
15
16
import com.alibaba.fastjson.JSON;
17
import com.alibaba.fastjson.serializer.SerializerFeature;
18
import com.google.gson.Gson;
19
20
import lombok.extern.slf4j.Slf4j;
21
22
/**
23
* 資料脫敏處理工具類
24
* @version 1.0
25
* @date 2018年9月18日下午5:23:05
26
*/
27
28
public class SensitiveInfoUtils {
29
30
/**
31
* 中文名
32
*/
33
public static final String CHINESE_NAME="01";
34
35
/**
36
* 身份證號
37
*/
38
public static final String ID_CARD="02";
39
/**
40
* 座機號
41
*/
42
public static final String TELE_PHONE="03";
43
/**
44
* 固定電話
45
*/
46
public static final String FIXED_PHONE="04";
47
/**
48
* 手機號
49
*/
50
public static final String MOBILE_PHONE="05";
51
/**
52
* 電話號碼(包括手機號和固定電話)
53
*/
54
public static final String PHONE="06";
55
/**
56
* 地址
57
*/
58
public static final String ADDRESS="07";
59
/**
60
* 電子郵件
61
*/
62
public static final String EMAIL="08";
63
/**
64
* 銀行卡
65
*/
66
public static final String BANK_CARD="09";
67
/**
68
* 公司開戶銀行聯號
69
*/
70
public static final String CNAPS_CODE="10";
71
/**
72
* 車輛識別號
73
*/
74
public static final String CAR_CODE="11";
75
/**
76
* 房源編號\土地稅源編號\土地使用證編號
77
*/
78
public static final String RESOURCE_CODE="12";
79
/**
80
* 車牌號
81
*/
82
public static final String PLATE_NUMBER="13";
83
84
/**
85
* [中文姓名] 只顯示第一個漢字,其他隱藏為2個星號<例子:李**>
86
*
87
* @param name
88
* @return
89
*/
90
public static String chineseName(String fullName) {
91
if (StringUtils.isBlank(fullName)) {
92
return "";
93
}
94
String name = StringUtils.left(fullName, 1);
95
return StringUtils.rightPad(name, StringUtils.length(fullName), "*");
96
}
97
98
/**
99
* [中文姓名] 只顯示第一個漢字,其他隱藏為2個星號<例子:李**>
100
*
101
* @param familyName
102