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

179 lines
3.9 KiB
Java

package com.imyeyu.utils;
import com.imyeyu.java.TimiJava;
import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiException;
import java.io.StringWriter;
import java.net.IDN;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Locale;
import java.util.Map;
/**
* 编码操作
*
* @author 夜雨
* @version 2021-02-13 10:59
*/
public class Encoder {
/**
* Unicode 编码全角字符
*
* @param data 字符串
* @return 编码结果
*/
public static String unicode(String data) {
StringWriter out = new StringWriter(data.length() * 2);
for (int i = 0, l = data.length(); i < l; i++) {
char c = data.charAt(i);
String cHex = Integer.toHexString(c).toUpperCase(Locale.ENGLISH);
if (0xFFF < c) {
out.write("\\u" + cHex);
} else if (0xFF < c) {
out.write("\\u0" + cHex);
} else if (0x7F < c) {
out.write("\\u00" + cHex);
} else if (c < 32) {
switch (c) {
case '\b' -> {
out.write('\\');
out.write('b');
}
case '\n' -> {
out.write('\\');
out.write('n');
}
case '\t' -> {
out.write('\\');
out.write('t');
}
case '\f' -> {
out.write('\\');
out.write('f');
}
case '\r' -> {
out.write('\\');
out.write('r');
}
default -> {
if (0xF < c) {
out.write("\\u00" + cHex);
} else {
out.write("\\u000" + cHex);
}
}
}
} else {
switch (c) {
case '\'' -> {
out.write('\\');
out.write('\'');
}
case '"' -> {
out.write('\\');
out.write('"');
}
case '\\' -> {
out.write('\\');
out.write('\\');
}
case '/' -> {
out.write('\\');
out.write('/');
}
default -> out.write(c);
}
}
}
return out.toString();
}
/**
* Base64 编码字符串
*
* @param data 字符串
* @return 编码结果
*/
public static String base64(String data) {
return base64(data.getBytes(StandardCharsets.UTF_8));
}
/**
* Base64 编码字节数据
*
* @param bytes 字节数据
* @return 编码结果
*/
public static String base64(byte[] bytes) {
return Base64.getEncoder().encodeToString(bytes);
}
/**
* 编码 URL 参数值。不要传整个链接,此方法只用于<u>参数值</u>的编码
*
* @param data URL 参数
* @return 编码结果
*/
public static String urlArg(String data) {
return URLEncoder.encode(data, StandardCharsets.UTF_8);
}
/**
* 编码 URL 参数
*
* @param args URL 参数表
* @return 编码结果
*/
public static String urlArgs(Map<String, Object> args) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, Object> param : args.entrySet()) {
sb.append('&').append(param.getKey()).append('=').append(urlArg(param.getValue().toString()));
}
return sb.substring(1);
}
/**
* 编码 URL 链接,半角 "+" 号会使用 "%2B"
*
* @param urlStr URL 链接
* @return 编码结果
*/
public static String url(String urlStr) {
if (TimiJava.isEmpty(urlStr)) {
return "";
}
try {
URL url = new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), IDN.toASCII(url.getHost()), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
return uri.toASCIIString().replace("+", "%2B");
} catch (MalformedURLException | URISyntaxException e) {
throw new TimiException(TimiCode.ERROR, e.getMessage());
}
}
/**
* 字节数据转 16 进制字符串
*
* @param bytes 字节数据
* @return 16 进制字符串
*/
public static String hex(byte[] bytes) {
final int l = bytes.length;
final char[] c = new char[l << 1];
for (int i = 0, j = 0; i < l; i++) {
c[j++] = Text.HEX_DIGITS_LOWER[(0xF0 & bytes[i]) >>> 4];
c[j++] = Text.HEX_DIGITS_LOWER[0x0F & bytes[i]];
}
return new String(c);
}
}