MiraiForum

    • 注册
    • 登录
    • 搜索
    • 热门
    • 最新
    • 未解决
    • 标签
    • 群组
    • 友情链接

    [Java][踩坑] 关于中文域名解析 Punycode 编码

    技术交流板块
    1
    1
    204
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • MrXiaoM
      MrXiaoM 童心未泯 最后由 编辑

      我有一个朋友,他买了个域名,然后绑了 CNAME 和 SRV 记录到我的 Minecraft 服务器上,但可惜的是,Minecraft 客户端并无 Punycode 编码域名支持,然后我用网络爬虫 (低情商: 百度) 搜找到了 Punycode 转码的码子,以为就一劳永逸了,结果这玩意并不完全,下面的是我补好可以直接用的轮子。写得不是很好,如有错希望大佬能指出

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

      CSDN

      那个朋友真不是我自己

      1 条回复 最后回复 回复 引用 0
      • 1 / 1
      • First post
        Last post
      Powered by Mamoe Technologies & NodeBB | 友情链接 | 服务监控 | Contact