掩码处理--方法二

package 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;
	}
}
x
649
1
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
@Slf4j
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
     * @param givenName
103
     * @return
104
     */
105
    public static String chineseName(String familyName, String givenName) {
106
        if (StringUtils.isBlank(familyName) || StringUtils.isBlank(givenName)) {
107
            return "";
108
        }
109
        return chineseName(familyName + givenName);
110
    }
111
112
    /**
113
     * [身份证号] 显示前6后2,其他隐藏。共计18位或者15位。<例子:*************5762>
114
     * 
115
     * @param id
116
     * @return
117
     */
118
    public static String idCardNum(String id) {
119
        if (StringUtils.isBlank(id)) {
120
            return "";
121
        }
122
        return StringUtils.left(id, 6).concat(StringUtils
123
                .removeStart(StringUtils.leftPad(StringUtils.right(id, 2), StringUtils.length(id), "*"), "******"));
124
    }
125
126
    /**
127
     * [固定电话] 后四位,其他隐藏<例子:****1234>
128
     * 
129
     * @param num
130
     * @return
131
     */
132
    public static String telePhone(String num) {
133
        if (StringUtils.isBlank(num)) {
134
            return "";
135
        }
136
        return StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*");
137
    }
138
139
    /**
140
     * [固定电话] 前两位,后两位,其他隐藏<例子:88**34>
141
     * 
142
     * @param num
143
     * @return
144
     */
145
    public static String fixedPhone(String num) {
146
        if (StringUtils.isBlank(num)) {
147
            return "";
148
        }
149
        return StringUtils.left(num, 2).concat(StringUtils
150
                .removeStart(StringUtils.leftPad(StringUtils.right(num, 2), StringUtils.length(num), "*"), "**"));
151
    }
152
153
    /**
154
     * [手机号码] 前三位,后四位,其他隐藏<例子:138******1234>
155
     * 
156
     * @param num
157
     * @return
158
     */
159
    public static String mobilePhone(String num) {
160
        if (StringUtils.isBlank(num)) {
161
            return "";
162
        }
163
        return StringUtils.left(num, 3).concat(StringUtils
164
                .removeStart(StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*"), "***"));
165
    }
166
167
    /**
168
     * [电话号码] 以/分开 前三位,后四位,其他隐藏<例子:138******1234/****1234>
169
     * 
170
     * @param num
171
     * @return
172
     */
173
    public static String phone(String num) {
174
        if (StringUtils.isBlank(num)) {
175
            return "";
176
        }
177
        String[] split = num.split("/");
178
        StringBuffer sb = new StringBuffer();
179
        if (split.length > 1) {
180
            for (String number : split) {
181
                number = number.trim();
182
                number = caseNum(number);
183
                sb.append(number).append("/");
184
            }
185
            num = sb.toString();
186
            if (num.endsWith("/")) {
187
                num = num.substring(0, num.length() - 1);
188
            }
189
        } else {
190
            num = num.trim();
191
            num = caseNum(num);
192
        }
193
        return num;
194
    }
195
196
    private static String caseNum(String num) {
197
        switch (num.length()) {
198
        case 7:
199
            num = fixedPhone(num);
200
            break;
201
        case 8:
202
            num = fixedPhone(num);
203
            break;
204
        case 11:
205
            num = mobilePhone(num);
206
            break;
207
        default:
208
            break;
209
        }
210
        return num;
211
    }
212
213
    /**
214
     * 数据长度大于12位,只显示前面sensitiveSize位<例子:北京市海淀区****>
215
     * 
216
     * @param address
217
     * @param sensitiveSize
218
     *            敏感信息长度
219
     * @return
220
     */
221
    private static String code_left(String address, int sensitiveSize) {
222
        if (StringUtils.isBlank(address)) {
223
            return "";
224
        }
225
        address=address.trim();
226
        return StringUtils.rightPad(StringUtils.left(address, sensitiveSize), StringUtils.length(address), "*");
227
    }
228
229
    /**
230
     * 数据长度小于于12位,从后往前数sensitiveSize位设置为*<例子:广州市******>
231
     * 
232
     * @param address
233
     * @param sensitiveSize
234
     *            敏感信息长度
235
     * @return
236
     */
237
    private static String code_right_hide(String address, int sensitiveSize) {
238
        if (StringUtils.isBlank(address)) {
239
            return "";
240
        }
241
        int length = StringUtils.length(address);
242
        return StringUtils.rightPad(StringUtils.left(address, length - sensitiveSize), length, "*");
243
    }
244
245
    /**
246
     * 数据从后往前数sensitiveSize显示<例子:***广州市天河区>
247
     * 
248
     * @param address
249
     * @param sensitiveSize
250
     * @return
251
     */
252
    @SuppressWarnings("unused")
253
    private static String code_right_display(String address, int sensitiveSize) {
254
        if (StringUtils.isBlank(address)) {
255
            return "";
256
        }
257
        String num = StringUtils.right(address, sensitiveSize);
258
        return StringUtils.leftPad(num, StringUtils.length(address), "*");
259
    }
260
261
    /**
262
     * [地址] 如长度大于等于12位,留前6位,其余为*,如少于12位,从后往前掩盖6位为*
263
     * 
264
     * @param address
265
     * @param sensitiveSize
266
     *            敏感信息长度
267
     * @return
268
     */
269
    public static String address(String address) {
270
        if (StringUtils.isBlank(address)) {
271
            return "";
272
        }
273
        int length = StringUtils.length(address);
274
        if (length >= 12) {
275
            return code_left(address, 6);
276
        } else {
277
            return code_right_hide(address, 6);
278
        }
279
    }
280
281
    /**
282
     * [电子邮箱] 邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示<例子:g**@163.com>
283
     * 
284
     * @param email
285
     * @return
286
     */
287
    public static String email(String email) {
288
        if (StringUtils.isBlank(email)) {
289
            return "";
290
        }
291
        int index = StringUtils.indexOf(email, "@");
292
        if (index <= 1)
293
            return email;
294
        else
295
            return StringUtils.rightPad(StringUtils.left(email, 1), index, "*")
296
                    .concat(StringUtils.mid(email, index, StringUtils.length(email)));
297
    }
298
299
    /**
300
     * [银行卡号] 前六位,后四位,其他用星号隐藏每位1个星号<例子:6222600**********1234>
301
     * 
302
     * @param cardNum
303
     * @return
304
     */
305
    public static String bankCard(String cardNum) {
306
        if (StringUtils.isBlank(cardNum)) {
307
            return "";
308
        }
309
        return StringUtils.left(cardNum, 6).concat(StringUtils.removeStart(
310
                StringUtils.leftPad(StringUtils.right(cardNum, 4), StringUtils.length(cardNum), "*"), "******"));
311
    }
312
313
    /**
314
     * [公司开户银行联号] 公司开户银行联行号,显示前两位,其他用星号隐藏,每位1个星号<例子:12********>
315
     * 
316
     * @param code
317
     * @return
318
     */
319
    public static String cnapsCode(String code) {
320
        if (StringUtils.isBlank(code)) {
321
            return "";
322
        }
323
        return StringUtils.rightPad(StringUtils.left(code, 2), StringUtils.length(code), "*");
324
    }
325
326
    /**
327
     * [车牌号] 车牌号,显示前4位,其他用星号隐藏,每位1个星号<例子:1222***>
328
     * 
329
     * @param code
330
     * @return
331
     */
332
    public static String plateNumber(String code) {
333
        if (StringUtils.isBlank(code)) {
334
            return "";
335
        }
336
        return StringUtils.rightPad(StringUtils.left(code, 4), StringUtils.length(code), "*");
337
    }
338
339
    /**
340
     * [车辆识别号] 车辆识别号,从后往前数8位设置为*,其他用星号隐藏,每位1个星号<例子:1222********>
341
     * 
342
     * @param code
343
     * @return
344
     */
345
    public static String carCode(String code) {
346
        if (StringUtils.isBlank(code)) {
347
            return "";
348
        }
349
        return code_right_hide(code, 8);
350
    }
351
352
    /**
353
     * [ 房源编号\土地税源编号\土地使用证编号] 房源编号,留开头3位,其余为*<例子:122***>
354
     * 
355
     * @param code
356
     * @return
357
     */
358
    public static String resourceCode(String code) {
359
        if (StringUtils.isBlank(code)) {
360
            return "";
361
        }
362
        return StringUtils.rightPad(StringUtils.left(code, 3), StringUtils.length(code), "*");
363
    }
364
365
    /**
366
     * 字符串反转
367
     * 
368
     * @param s
369
     * @return
370
     */
371
    @SuppressWarnings("unused")
372
    private static String reverseStringBuilder(String s) {
373
        StringBuilder sb = new StringBuilder(s);
374
        String afterreverse = sb.reverse().toString();
375
        return afterreverse;
376
    }
377
378
    /**
379
     * 获取脱敏json串 <注意:递归引用会导致java.lang.StackOverflowError>
380
     * 
381
     * @param javaBean
382
     * @return
383
     */
384
    public static String getJson(Object javaBean) {
385
        String json = null;
386
        if (null != javaBean) {
387
            Class<? extends Object> raw = javaBean.getClass();
388
            try {
389
                if (raw.isInterface())
390
                    return json;
391
                Gson g = new Gson();
392
                Object clone = g.fromJson(g.toJson(javaBean, javaBean.getClass()), javaBean.getClass());
393
                Set<Integer> referenceCounter = new HashSet<Integer>();
394
                SensitiveInfoUtils.replace(SensitiveInfoUtils.findAllField(raw), clone, referenceCounter);
395
                json = JSON.toJSONString(clone, SerializerFeature.WriteMapNullValue,
396
                        SerializerFeature.WriteNullListAsEmpty);
397
                referenceCounter.clear();
398
                referenceCounter = null;
399
            } catch (Throwable e) {
400
                log.error("SensitiveInfoUtils.getJson() ERROR", e);
401
            }
402
        }
403
        return json;
404
    }
405
406
    private static Field[] findAllField(Class<?> clazz) {
407
        Field[] fileds = clazz.getDeclaredFields();
408
        while (null != clazz.getSuperclass() && !Object.class.equals(clazz.getSuperclass())) {
409
            fileds = (Field[]) ArrayUtils.addAll(fileds, clazz.getSuperclass().getDeclaredFields());
410
            clazz = clazz.getSuperclass();
411
        }
412
        return fileds;
413
    }
414
415
    private static void replace(Field[] fields, Object javaBean, Set<Integer> referenceCounter)
416
            throws IllegalArgumentException, IllegalAccessException {
417
        if (null != fields && fields.length > 0) {
418
            for (Field field : fields) {
419
                field.setAccessible(true);
420
                if (null != field && null != javaBean) {
421
                    Object value = field.get(javaBean);
422
                    if (null != value) {
423
                        Class<?> type = value.getClass();
424
                        // 1.处理子属性,包括集合中的
425
                        if (type.isArray()) {
426
                            int len = Array.getLength(value);
427
                            for (int i = 0; i < len; i++) {
428
                                Object arrayObject = Array.get(value, i);
429
                                SensitiveInfoUtils.replace(SensitiveInfoUtils.findAllField(arrayObject.getClass()),
430
                                        arrayObject, referenceCounter);
431
                            }
432
                        } else if (value instanceof Collection<?>) {
433
                            Collection<?> c = (Collection<?>) value;
434
                            Iterator<?> it = c.iterator();
435
                            while (it.hasNext()) {
436
                                Object collectionObj = it.next();
437
                                SensitiveInfoUtils.replace(SensitiveInfoUtils.findAllField(collectionObj.getClass()),
438
                                        collectionObj, referenceCounter);
439
                            }
440
                        } else if (value instanceof Map<?, ?>) {
441
                            Map<?, ?> m = (Map<?, ?>) value;
442
                            Set<?> set = m.entrySet();
443
                            for (Object o : set) {
444
                                Entry<?, ?> entry = (Entry<?, ?>) o;
445
                                Object mapVal = entry.getValue();
446
                                SensitiveInfoUtils.replace(SensitiveInfoUtils.findAllField(mapVal.getClass()), mapVal,
447
                                        referenceCounter);
448
                            }
449
                        } else if (!type.isPrimitive() && !StringUtils.startsWith(type.getPackage().getName(), "javax.")
450
                                && !StringUtils.startsWith(type.getPackage().getName(), "java.")
451
                                && !StringUtils.startsWith(field.getType().getName(), "javax.")
452
                                && !StringUtils.startsWith(field.getName(), "java.")
453
                                && referenceCounter.add(value.hashCode())) {
454
                            SensitiveInfoUtils.replace(SensitiveInfoUtils.findAllField(type), value, referenceCounter);
455
                        }
456
                    }
457
                    // 2. 处理自身的属性
458
                    SensitiveInfo annotation = field.getAnnotation(SensitiveInfo.class);
459
                    if (field.getType().equals(String.class) && null != annotation) {
460
                        String valueStr = (String) value;
461
                        if (StringUtils.isNotBlank(valueStr)) {
462
                            switch (annotation.type()) {
463
                            case CHINESE_NAME: {
464
                                field.set(javaBean, SensitiveInfoUtils.chineseName(valueStr));
465
                                break;
466
                            }
467
                            case ID_CARD: {
468
                                field.set(javaBean, SensitiveInfoUtils.idCardNum(valueStr));
469
                                break;
470
                            }
471
                            case TELE_PHONE: {
472
                                field.set(javaBean, SensitiveInfoUtils.telePhone(valueStr));
473
                                break;
474
                            }
475
                            case FIXED_PHONE: {
476
                                field.set(javaBean, SensitiveInfoUtils.fixedPhone(valueStr));
477
                                break;
478
                            }
479
                            case MOBILE_PHONE: {
480
                                field.set(javaBean, SensitiveInfoUtils.mobilePhone(valueStr));
481
                                break;
482
                            }
483
                            case PHONE: {
484
                                field.set(javaBean, SensitiveInfoUtils.phone(valueStr));
485
                                break;
486
                            }
487
                            case ADDRESS: {
488
                                field.set(javaBean, SensitiveInfoUtils.address(valueStr));
489
                                break;
490
                            }
491
                            case EMAIL: {
492
                                field.set(javaBean, SensitiveInfoUtils.email(valueStr));
493
                                break;
494
                            }
495
                            case BANK_CARD: {
496
                                field.set(javaBean, SensitiveInfoUtils.bankCard(valueStr));
497
                                break;
498
                            }
499
                            case CNAPS_CODE: {
500
                                field.set(javaBean, SensitiveInfoUtils.cnapsCode(valueStr));
501
                                break;
502
                            }
503
                            case PLATE_NUMBER: {
504
                                field.set(javaBean, SensitiveInfoUtils.plateNumber(valueStr));
505
                                break;
506
                            }
507
                            case CAR_CODE: {
508
                                field.set(javaBean, SensitiveInfoUtils.carCode(valueStr));
509
                                break;
510
                            }
511
                            case RESOURCE_CODE: {
512
                                field.set(javaBean, SensitiveInfoUtils.resourceCode(valueStr));
513
                                break;
514
                            }
515
                            }
516
                        }
517
                    }
518
                }
519
            }
520
        }
521
    }
522
523
    public static String mask(String code,String type){
524
        
525
        if (StringUtils.isNotBlank(code)&&StringUtils.isNotBlank(type)) {
526
            code = code.trim();
527
            switch (type) {
528
            case CHINESE_NAME: {
529
                code = SensitiveInfoUtils.chineseName(code);
530
                break;
531
            }
532
            case ID_CARD: {
533
                code = SensitiveInfoUtils.idCardNum(code);
534
                break;
535
            }
536
            case TELE_PHONE: {
537
                code = SensitiveInfoUtils.telePhone(code);
538
                break;
539
            }
540
            case FIXED_PHONE: {
541
                code =SensitiveInfoUtils.fixedPhone(code);
542
                break;
543
            }
544
            case MOBILE_PHONE: {
545
                code = SensitiveInfoUtils.mobilePhone(code);
546
                break;
547
            }
548
            case PHONE: {
549
                code = SensitiveInfoUtils.phone(code);
550
                break;
551
            }
552
            case ADDRESS: {
553
                code = SensitiveInfoUtils.address(code);
554
                break;
555
            }
556
            case EMAIL: {
557
                code =SensitiveInfoUtils.email(code);
558
                break;
559
            }
560
            case BANK_CARD: {
561
                code =SensitiveInfoUtils.bankCard(code);
562
                break;
563
            }
564
            case CNAPS_CODE: {
565
                code =SensitiveInfoUtils.cnapsCode(code);
566
                break;
567
            }
568
            case PLATE_NUMBER: {
569
                code = SensitiveInfoUtils.plateNumber(code);
570
                break;
571
            }
572
            case CAR_CODE: {
573
                code =SensitiveInfoUtils.carCode(code);
574
                break;
575
            }
576
            case RESOURCE_CODE: {
577
                code =SensitiveInfoUtils.resourceCode(code);
578
                break;
579
            }
580
            }
581
        }
582
        
583
        return code;
584
    }
585
    
586
    // ----------------------------------------------------------------------------------------------
587
    public static Method[] findAllMethod(Class<?> clazz) {
588
        Method[] methods = clazz.getMethods();
589
        return methods;
590
    }
591
592
    // ----------------------------------------------------------------------------------------------
593
    public static enum SensitiveType {
594
        /**
595
         * 中文名
596
         */
597
        CHINESE_NAME,
598
599
        /**
600
         * 身份证号
601
         */
602
        ID_CARD,
603
        /**
604
         * 座机号
605
         */
606
        TELE_PHONE,
607
        /**
608
         * 固定电话
609
         */
610
        FIXED_PHONE,
611
        /**
612
         * 手机号
613
         */
614
        MOBILE_PHONE,
615
        /**
616
         * 电话号码(包括手机号和固定电话)
617
         */
618
        PHONE,
619
        /**
620
         * 地址
621
         */
622
        ADDRESS,
623
        /**
624
         * 电子邮件
625
         */
626
        EMAIL,
627
        /**
628
         * 银行卡
629
         */
630
        BANK_CARD,
631
        /**
632
         * 公司开户银行联号
633
         */
634
        CNAPS_CODE,
635
        /**
636
         * 车辆识别号
637
         */
638
        CAR_CODE,
639
        /**
640
         * 房源编号\土地税源编号\土地使用证编号
641
         */
642
        RESOURCE_CODE,
643
        /**
644
         * 车牌号
645
         */
646
        PLATE_NUMBER;
647
    }
648
}
649

package com.foresee.zxpt.common.mask;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface SensitiveInfo {
 
    public SensitiveInfoUtils.SensitiveType type() ;
}
1
17
 
1
package com.foresee.zxpt.common.mask;
2
3
import java.lang.annotation.Documented;
4
import java.lang.annotation.ElementType;
5
import java.lang.annotation.Inherited;
6
import java.lang.annotation.Retention;
7
import java.lang.annotation.RetentionPolicy;
8
import java.lang.annotation.Target;
9
10
@Target({ElementType.FIELD,ElementType.METHOD})
11
@Retention(RetentionPolicy.RUNTIME)
12
@Inherited
13
@Documented
14
public @interface SensitiveInfo {
15
 
16
    public SensitiveInfoUtils.SensitiveType type() ;
17
}

package com.foresee.common.mask;

import com.foresee.common.mask.SensitiveInfoUtils.SensitiveType;

import lombok.Data;

public class Test {

	public static void main(String[] args) {
//		String num="13257917009/8888888";
//		String phone = SensitiveInfoUtils.phone(num);
//		System.out.println(phone);
		User user =new Test().new User();
		user.setAddress("广东省广州市天河区鸡山村");
		user.setIdCard("362228199208142414");
		user.setPhone("13257917009/12345678");
		user.setResource("1234567890");
		String json = SensitiveInfoUtils.getJson(user);
		System.out.println(json);
	}
	
	@Data
	class User{
		@SensitiveInfo(type=SensitiveType.PHONE)
		String phone;
		@SensitiveInfo(type=SensitiveType.ADDRESS)
		String address;
		@SensitiveInfo(type=SensitiveType.RESOURCE_CODE)
		String resource;
		@SensitiveInfo(type=SensitiveType.ID_CARD)
		String idCard;
	}
}
1
34
1
package com.foresee.common.mask;
2
3
import com.foresee.common.mask.SensitiveInfoUtils.SensitiveType;
4
5
import lombok.Data;
6
7
public class Test {
8
9
    public static void main(String[] args) {
10
//      String num="13257917009/8888888";
11
//      String phone = SensitiveInfoUtils.phone(num);
12
//      System.out.println(phone);
13
        User user =new Test().new User();
14
        user.setAddress("广东省广州市天河区鸡山村");
15
        user.setIdCard("362228199208142414");
16
        user.setPhone("13257917009/12345678");
17
        user.setResource("1234567890");
18
        String json = SensitiveInfoUtils.getJson(user);
19
        System.out.println(json);
20
    }
21
    
22
    @Data
23
    class User{
24
        @SensitiveInfo(type=SensitiveType.PHONE)
25
        String phone;
26
        @SensitiveInfo(type=SensitiveType.ADDRESS)
27
        String address;
28
        @SensitiveInfo(type=SensitiveType.RESOURCE_CODE)
29
        String resource;
30
        @SensitiveInfo(type=SensitiveType.ID_CARD)
31
        String idCard;
32
    }
33
}
34

猜你喜欢

转载自www.cnblogs.com/gz9218/p/2f164a001eaf74bb45dd79f0ef61f908.html