Rfc3492Idn implements Idn { protected String decode(String input) { int n = initial_n; int i = 0; int bias = initial_bias; StringBuilder output = new StringBuilder(input.length()); int lastdelim = input.lastIndexOf(delimiter); if (lastdelim != -1) { output.append(input.subSequence(0, lastdelim)); input = input.substring(lastdelim + 1); } while (input.length() > 0) { int oldi = i; int w = 1; for (int k = base;; k += base) { if (input.length() == 0) break; char c = input.charAt(0); input = input.substring(1); int digit = digit(c); i = i + digit * w; int t; if (k <= bias + tmin) { t = tmin; } else if (k >= bias + tmax) { t = tmax; } else { t = k - bias; } if (digit < t) break; w = w * (base - t); } bias = adapt(i - oldi, output.length() + 1, (oldi == 0)); n = n + i / (output.length() + 1); i = i % (output.length() + 1); output.insert(i, (char) n); i++; } return output.toString(); }  String toUnicode(String punycode);  }
@Test public void testDecode() throws Exception { Rfc3492Idn idn = new Rfc3492Idn(); Assert.assertEquals("\u0644\u064A\u0647\u0645\u0627\u0628\u062A\u0643\u0644" + "\u0645\u0648\u0634\u0639\u0631\u0628\u064A\u061F", idn.decode("egbpdaj6bu4bxfgehfvwxn")); Assert.assertEquals("\u4ED6\u4EEC\u4E3A\u4EC0\u4E48\u4E0D\u8BF4\u4E2D\u6587", idn.decode("ihqwcrb4cv8a8dqg056pqjye")); Assert.assertEquals("\u043F\u043E\u0447\u0435\u043C\u0443\u0436\u0435\u043E"+ "\u043D\u0438\u043D\u0435\u0433\u043E\u0432\u043E\u0440"+ "\u044F\u0442\u043F\u043E\u0440\u0443\u0441\u0441\u043A"+ "\u0438", idn.decode("b1abfaaepdrnnbgefbaDotcwatmq2g4l")); Assert.assertEquals("\u004D\u0061\u006A\u0069\u3067\u004B\u006F\u0069\u3059" + "\u308B\u0035\u79D2\u524D", idn.decode("MajiKoi5-783gue6qz075azm5e")); }