package com.visy.utils;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.util.Arrays;
public class LogUtil {
/**
* 安全的JSON字符串转换(可脱敏)
* @param obj 待序列化对象
* @param fieldNames 待脱敏的字段名称
* @return JSON字符串
*/
public static String toJsonSafety(Object obj, String... fieldNames){
if(fieldNames==null || fieldNames.length==0){
return toJson(obj);
}
JSONObject jsonObject = (JSONObject) JSON.toJSON( obj);
for(String fieldName : fieldNames){
Object value = jsonObject.get(fieldName);
if(ObjectUtil.isNotNull(value)){
jsonObject.put(fieldName, mask(value.toString()));
}
}
return toJson(jsonObject);
}
private static String toJson(Object obj){
return JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue);
}
/**
* 字符串脱敏方法(自动计算并隐藏部分字符)
* @param value 待脱敏的字符串
* @return 脱敏后的字符串
*/
public static String mask(String value){
if(value == null || value.isEmpty()){
return value;
}
int length = value.length(), halfLength = length / 2;
if(halfLength <= 1){ // 1 ~ 3 个字符, 全部脱敏
return createRepeatedString('*', length);
}else{ // >= 4 个字符, 前后各保留1/4 个字符
int beforeLength = halfLength / 2;
return mask(value, '*', beforeLength, halfLength-beforeLength);
}
}
/**
* 数据脱敏方法
* @param value 待脱敏的原始数据
* @param ch 脱敏占位字符
* @param beforeLength 前保留字符数
* @param afterLength 后保留字符数
* @return 脱敏后的数据
*/
public static String mask(String value, char ch, int beforeLength, int afterLength) {
// 空值安全检查
if (value == null || value.isEmpty()) {
return value;
}
final int length = value.length(), leastLength = beforeLength + afterLength;
// 长度小于等于leastLength位,全部脱敏
if (length <= leastLength) {
if(length <= afterLength){
// 剩余长度小于等于afterLength,全部脱敏
return createRepeatedString(ch, length);
}
// 剩余长度大于afterLength,只脱敏前length-afterLength位
return createRepeatedString(ch, length-afterLength) + value.substring(length-afterLength);
}
return value.substring(0, beforeLength) + createRepeatedString(ch, length-leastLength) + value.substring(length-afterLength);
}
/**
* 创建重复字符的字符串
* @param ch 要重复的字符
* @param count 重复次数
* @return 重复字符组成的字符串
*/
private static String createRepeatedString(char ch, int count) {
if (count <= 0) {
return "";
}
char[] chars = new char[count];
Arrays.fill(chars, ch);
return new String(chars);
}
}