一、前言
零宽字符顾名思义,零宽度不可见的字符。在笔者小时候玩网络游戏的时候,总看到有一些大佬顶着空白名的ID,自己去取空白名又提示不能为空,让人火大。现在想想,可能就是打入的零宽字符,本着想到就去尝试一下的态度,在网上搜索了一下,总结出了这篇博文,实现java方法零宽字符的转换和解密。
二、实现逻辑
//定义零宽字符转换map
private static final Map<String,String> zeroWidthMap=new HashMap() {
{
put("0","\u200e");
put("1","\u200f");
put("split","\u200c");
put("\u200e","0");
put("\u200f","1");
}
};
/**
* 普通字符串转为零宽字符串
* @param str
* @return
*/
public static String strToZeroWidthStr(String str) {
String result="";
if(str!=null&&str.length()>0) {//字符非空判断
result=Arrays.stream(str.split(""))
.map(
item ->Integer.toBinaryString(item.charAt(0))//字符拆分,转为二进制数据
)
.map(
item ->Arrays.stream(item.split(""))
.map(
zeroOrOne ->zeroWidthMap.get(zeroOrOne)//零宽字符替换二进制数据
).collect(
Collectors.joining("")
)
)
.collect(
Collectors.joining(zeroWidthMap.get("split"))//字符间零宽分隔符拼接
);
}
return result;
}
/**
* 零宽字符串转为普通字符串
* @param str
* @return
*/
public static String zeroWidthStrToStr(String str) {
String result="";
if(str!=null&&str.length()>0) {//字符非空判断
result=Arrays.stream(str.split(zeroWidthMap.get("split")))//零宽字符串分隔数组
.map(
item -> Arrays.stream(item.split(""))
.map(
zeroWidthStr -> zeroWidthMap.get(zeroWidthStr)//二进制数据替换零宽字符
).collect(
Collectors.joining("")
)
).map(
item -> "" +(char)Integer.parseInt(item, 2)//二进制数据转为对应字符
)
.collect(
Collectors.joining("")
);
}
return result;
}
/**
* 零宽字符串解密
* @param str
* @return
*/
public static String zeroWidthStrDecrypt(String str) {
String result="";
if(str!=null&&str.length()>0) {//字符非空判断
String[] charArr=str.split("");
String regex="[\u200b-\u200f]";
String zeroWidthStr="";
for(String charStr : charArr) {//字符遍历
if(charStr.matches(regex)) {//判断是否零宽字符
zeroWidthStr+=charStr;//零宽字符拼接
}else {
if(!StringUtils.isEmpty(zeroWidthStr)) {//零宽字符非空
result+=zeroWidthStrToStr(zeroWidthStr);//零宽字符转换、拼接
zeroWidthStr="";
}
result+=charStr;//最终字符拼接
}
}
}
return result;
}
三、程序运行
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
String str="这是一个"+strToZeroWidthStr("隐藏的")+"秘密";
System.out.println("---明文:"+str);
str=zeroWidthStrDecrypt(str);
System.out.println("---密文:"+str);
}