Java 中文域名解析 | Punycode 网址编码

(Punycode编码转换部分来自 Punycode与中文互转)
用法: Punycode.encodeURL(url)
举个例子: Punycode.encodeURL("我的世界.games");
这个例子返回的值是 xn--rhqx00c95nv9a.games

public class Punycode {
	private static int TMIN = 1;
	private static int TMAX = 26;
	private static int BASE = 36;
	private static int INITIAL_N = 128;
	private static int INITIAL_BIAS = 72;
	private static int DAMP = 700;
	private static int SKEW = 38;
	private static char DELIMITER = '-';

	public static String encodeURL(String url) {
		if (!url.contains("."))
			return url;
		String mainContent = url.substring(0, url.lastIndexOf("."));
		String prefix = mainContent.contains(".") ? mainContent.substring(0, mainContent.lastIndexOf(".") + 1) : "";
		if (mainContent.contains("."))
			mainContent = mainContent.substring(mainContent.lastIndexOf(".") + 1);
		mainContent = Punycode.encode(mainContent, "xn--");
		String suffix = url.substring(url.lastIndexOf("."));
		return prefix + mainContent + suffix;
	}

	/**
	 * 
	 * Punycodes a unicode string. THIS IS NOT SUITABLE FOR UNICODE AND LETTER
	 * MIXING
	 *
	 * @param input Unicode string.
	 * 
	 * @return Punycoded string, but original text for throw an exception
	 * 
	 */
	public static String encode(String input) {
		return Punycode.encode(input, "");
	}

	/**
	 * 
	 * Punycodes a unicode string. THIS IS NOT SUITABLE FOR UNICODE AND LETTER
	 * MIXING
	 *
	 * @param input Unicode string.
	 * 
	 * @return Punycoded string, but original text for throw an exception
	 * 
	 */
	public static String encode(String input, String successPrefix) {
		int n = INITIAL_N;
		int delta = 0;
		int bias = INITIAL_BIAS;
		StringBuilder output = new StringBuilder();
		int b = 0;
		for (int i = 0; i < input.length(); i++) {
			char c = input.charAt(i);
			if (isBasic(c)) {
				output.append(c);
				b++;
			}
		}
		if(b >= input.length()) return output.toString();
		if (b > 0) {
			output.append(DELIMITER);
		}
		int h = b;
		while (h < input.length()) {
			int m = Integer.MAX_VALUE;
			for (int i = 0; i < input.length(); i++) {
				int c = input.charAt(i);
				if (c >= n && c < m) {
					m = c;
				}
			}
			if (m - n > (Integer.MAX_VALUE - delta) / (h + 1)) {
				return input;
			}
			delta = delta + (m - n) * (h + 1);
			n = m;
			for (int j = 0; j < input.length(); j++) {
				int c = input.charAt(j);
				if (c < n) {
					delta++;
					if (0 == delta) {
						return input;
					}
				}
				if (c == n) {
					int q = delta;
					for (int k = BASE;; k += BASE) {
						int t;

						if (k <= bias) {
							t = TMIN;
						} else if (k >= bias + TMAX) {
							t = TMAX;
						} else {
							t = k - bias;
						}
						if (q < t) {
							break;
						}
						output.append((char) digit2codepoint(t + (q - t) % (BASE - t)));
						q = (q - t) / (BASE - t);
					}
					output.append((char) digit2codepoint(q));
					bias = adapt(delta, h + 1, h == b);
					delta = 0;
					h++;
				}
			}
			delta++;
			n++;
		}
		output.insert(0, successPrefix);
		return output.toString();
	}

	private static int adapt(int delta, int numpoints, boolean first) {
		if (first) {
			delta = delta / DAMP;
		} else {
			delta = delta / 2;
		}
		delta = delta + (delta / numpoints);
		int k = 0;
		while (delta > ((BASE - TMIN) * TMAX) / 2) {
			delta = delta / (BASE - TMIN);
			k = k + BASE;
		}
		return k + ((BASE - TMIN + 1) * delta) / (delta + SKEW);
	}

	private static boolean isBasic(char c) {
		return c < 0x80;
	}

	private static int digit2codepoint(int d) {
		if (d < 26) {
			return d + 'a';
		} else if (d < 36) {
			return d - 26 + '0';
		} else {
			return d;
		}
	}
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

懒怠的小猫Official

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值