脱敏思路
在Java中,String类中的codepoint相关方法用于处理Unicode代码点(code point)。一个代码点是一个Unicode字符的唯一编号。在Java中,字符串内部是以UTF-16编码存储的,这意味着大多数常见字符用一个char表示(占2个字节),而某些不常见的字符(即补充字符或四字节字符)则需要两个char(称为代理对)来表示。
核心方法
1. int codePointAt(int index):返回字符串中指定索引处的代码点。它处理代理对,确保返回正确的代码点。
2. int codePointBefore(int index):返回字符串中指定索引之前的代码点。
3. int codePointCount(int beginIndex, int endIndex):返回指定范围内的代码点数量。
4. int offsetByCodePoints(int index, int codePointOffset):返回从指定索引开始的代码点偏移量处的索引。
5. static int toChars(int codePoint, char[] dst, int dstIndex):将一个代码点转换为一个或两个char,并存储在字符数组中。
实现方法
public class NameMasking {
/**
* 对姓名进行脱敏处理
*
* @param name 需要脱敏的姓名
* @return 脱敏后的姓名
*/
public static String maskName(String name) {
if (name == null || name.isEmpty()) {
return name;
}
if (name.length() == 1) {
return name;
}
StringBuilder result = new StringBuilder();
//获取codePoint数量,
int codePointCount = name.codePointCount(0, name.length());
//获取第一个代码点的坐标
int firCodeIndex = name.offsetByCodePoints(0, 0);
//获取左后一个代码点的坐标
int lstCodeIndex = name.offsetByCodePoints(0, codePointCount - 1);
//循环处理
for (int index = firCodeIndex; index <= lstCodeIndex; ) {
//获取当前代码点
int codePoint = name.codePointAt(index);
//获取当前代码点长度
int charCount = Character.charCount(codePoint);
//判断是否是第一个字或者最后一个字
if (index == firCodeIndex || index == lstCodeIndex) {
//第一个字和最后一个字正常显示,截取字符串的时候需要考虑代码点长度
result.append(name, index, index + charCount);
} else {
//中间字使用*
result.append("*");
}
//跳转到下一个代码点坐标
index += charCount;
}
return result.toString();
}
public static void main(String[] args) {
String name1 = "张三";
String name2 = "李四五";
String name3 = "赵钱孙李";
String name4 = "𠮷𠮷𠮷𡃁𡈼";
String name5 = "𠮷𠮷𠮷";
String name6 = "吉野家";
System.out.println(maskName(name1)); // 输出: 张三
System.out.println(maskName(name2)); // 输出: 李*五
System.out.println(maskName(name3)); // 输出: 赵***李
System.out.println(maskName(name4)); // 输出: 𠮷***𡈼
System.out.println(maskName(name5)); // 输出: 𠮷*𠮷
System.out.println(maskName(name6)); // 输出: 吉*家
}
}
大家有什么好的想法,欢迎一起来讨论。