145 lines
3.4 KiB
Java
145 lines
3.4 KiB
Java
package com.imyeyu.utils;
|
|
|
|
import com.imyeyu.java.bean.timi.TimiCode;
|
|
import com.imyeyu.java.bean.timi.TimiException;
|
|
|
|
import java.io.StringWriter;
|
|
import java.io.UnsupportedEncodingException;
|
|
import java.net.URLDecoder;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.Base64;
|
|
|
|
/**
|
|
* 编码操作
|
|
*
|
|
* @author 夜雨
|
|
* @version 2021-02-13 10:59
|
|
*/
|
|
public class Decoder {
|
|
|
|
/**
|
|
* 解码 Unicode 字符串
|
|
*
|
|
* @param data Unicode 字符串
|
|
* @return 解码结果
|
|
*/
|
|
public static String unicode(String data) {
|
|
StringWriter out = new StringWriter(data.length());
|
|
|
|
StringBuilder unicode = new StringBuilder(4);
|
|
boolean hadSlash = false;
|
|
boolean inUnicode = false;
|
|
for (int i = 0, l = data.length(); i < l; i++) {
|
|
char c = data.charAt(i);
|
|
if (inUnicode) {
|
|
unicode.append(c);
|
|
if (unicode.length() == 4) {
|
|
try {
|
|
out.write((char) Integer.parseInt(unicode.toString(), 16));
|
|
unicode.setLength(0);
|
|
inUnicode = false;
|
|
} catch (NumberFormatException nfe) {
|
|
throw new TimiException(TimiCode.ERROR, "Unable to parse unicode value: " + unicode);
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
if (hadSlash) {
|
|
hadSlash = false;
|
|
switch (c) {
|
|
case '\\' -> out.write('\\');
|
|
case '\'' -> out.write('\'');
|
|
case '\"' -> out.write('"');
|
|
case 'r' -> out.write('\r');
|
|
case 'f' -> out.write('\f');
|
|
case 't' -> out.write('\t');
|
|
case 'n' -> out.write('\n');
|
|
case 'b' -> out.write('\b');
|
|
case 'u' -> inUnicode = true;
|
|
default -> out.write(c);
|
|
}
|
|
continue;
|
|
} else if (c == '\\') {
|
|
hadSlash = true;
|
|
continue;
|
|
}
|
|
out.write(c);
|
|
}
|
|
if (hadSlash) {
|
|
out.write('\\');
|
|
}
|
|
return out.toString();
|
|
}
|
|
|
|
/**
|
|
* 解码 Base64 字符串
|
|
*
|
|
* @param data Base64 字符串
|
|
* @return 解码结果
|
|
*/
|
|
public static byte[] base64(String data) {
|
|
return Base64.getDecoder().decode(data);
|
|
}
|
|
|
|
/**
|
|
* 解码 Base64 字符串
|
|
*
|
|
* @param data Base64 字符串
|
|
* @return 解码结果
|
|
*/
|
|
public static String base64String(String data) {
|
|
return new String(base64(data), StandardCharsets.UTF_8);
|
|
}
|
|
|
|
/**
|
|
* 解码 URL 链接
|
|
*
|
|
* @param url 已编码的 URL 链接
|
|
* @return 解码结果
|
|
*/
|
|
public static String url(String url) {
|
|
if (url == null) {
|
|
return "";
|
|
}
|
|
return URLDecoder.decode(url, StandardCharsets.UTF_8);
|
|
}
|
|
|
|
/**
|
|
* 16 进制字符串转字节数据
|
|
*
|
|
* @param hex 16 进制字符串
|
|
* @return 字节数据
|
|
* @throws UnsupportedEncodingException 不支持的编码
|
|
*/
|
|
public static byte[] hex(String hex) throws UnsupportedEncodingException {
|
|
final char[] c = hex.toCharArray();
|
|
final byte[] b = new byte[c.length >> 1];
|
|
|
|
final int len = c.length;
|
|
if ((len & 0x01) != 0) {
|
|
throw new UnsupportedEncodingException("Odd number of characters.");
|
|
}
|
|
|
|
final int outLen = len >> 1;
|
|
if (c.length < outLen) {
|
|
throw new UnsupportedEncodingException("Output array is not large enough to accommodate decoded data.");
|
|
}
|
|
for (int i = 0, j = 0; j < len; i++) {
|
|
int f = toDigit(c[j], j) << 4;
|
|
j++;
|
|
f = f | toDigit(c[j], j);
|
|
j++;
|
|
b[i] = (byte) (f & 0xFF);
|
|
}
|
|
return b;
|
|
}
|
|
|
|
private static int toDigit(final char ch, final int index) throws UnsupportedEncodingException {
|
|
final int digit = Character.digit(ch, 16);
|
|
if (digit == -1) {
|
|
throw new UnsupportedEncodingException("Illegal hexadecimal character " + ch + " at index " + index);
|
|
}
|
|
return digit;
|
|
}
|
|
}
|