Files
timi-utils/src/main/java/com/imyeyu/utils/Decoder.java
2026-01-04 15:26:45 +08:00

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;
}
}