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