问题背景
SMTP邮件正文使用的是GBK编码,目前zeek解析出来的日志是乱码,导致中文无法正常识别,无法做敏感姓名检测。但是身份证卡号手机都是数字 这种就能正常识别
编码例子
\xc9\xed\xb7\xdd֤\xa3\xba322393199404269880\xd0\xd5\xc3\xfb\xa3\xba\xcd\xf5С\xc3\xf7\xd2\xf8\xd0п\xa8\xbaţ\xba6667639037575418\xcaֻ\xfa\xa3\xba18810233456--Spirent_Avalanche_SMTP--
其中存在这乱码
不能直接将\x替换为%,然后通过URLDecoder.decode(“GBK编码”, “GBK”)转码,会乱码。
解决办法
先将zeek解析出来的编码转换成正常的GBK编码,在将GBK编码转换成中文。
import org.apache.commons.lang3.StringEscapeUtils;
import java.math.BigInteger;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
public class TestGBK {
public static void main(String[] args) throws Exception {
String a = "\\xc9\\xed\\xb7\\xdd֤\\xa3\\xba322393199404269880\\xd0\\xd5\\xc3\\xfb\\xa3\\xba\\xcd\\xf5С\\xc3\\xf7\\xd2\\xf8\\xd0п\\xa8\\xbaţ\\xba6667639037575418\\xcaֻ\\xfa\\xa3\\xba18810233456--Spirent_Avalanche_SMTP--";
//String a = "d֤";
//String b = "";
StringBuffer b = new StringBuffer();
for (int i = 0; i < a.length(); i++) {
char ch = a.charAt(i);
if ((int) ch > 127) {
// 特殊字符
b.append(str2Hex(String.valueOf(ch)));
} else {
b.append(ch);
}
}
System.out.println(b);
String s = StringEscapeUtils.escapeJava(b.toString()).replace("\\\\x", "%");
/*String s2 = StringEscapeUtils.escapeJava(b.toString()).replaceAll("\\\\\\\\x", "%");
System.out.println(StringEscapeUtils.escapeJava(b.toString()));
System.out.println(s);
System.out.println(s2);*/
String gbk = URLDecoder.decode(s, "GBK");
System.out.println(gbk);
}
public static String str2Hex(String str) {
String hexRaw = String.format("%x", new BigInteger(1, str.getBytes(StandardCharsets.UTF_8)));
char[] hexRawArr = hexRaw.toCharArray();
StringBuilder hexFmtStr = new StringBuilder();
final String SEP = "\\x";
for (int i = 0; i < hexRawArr.length; i++) {
hexFmtStr.append(SEP).append(hexRawArr[i]).append(hexRawArr[++i]);
}
return hexFmtStr.toString();
}
}