1 23 24 package org.jivesoftware.stringprep; 25 26 public class IDNA { 27 public final static String ACE_PREFIX = "xn--"; 28 29 38 public static String toASCII(String input) 39 throws IDNAException { 40 StringBuilder o = new StringBuilder (); 41 StringBuilder h = new StringBuilder (); 42 43 for (int i = 0; i < input.length(); i++) { 44 char c = input.charAt(i); 45 if (c == '.' || c == '\u3002' || c == '\uff0e' || c == '\uff61') { 46 o.append(toASCII(h.toString(), false, true)); 47 o.append(c); 48 h = new StringBuilder (); 49 } else { 50 h.append(c); 51 } 52 } 53 o.append(toASCII(h.toString(), false, true)); 54 return o.toString(); 55 } 56 57 67 public static String toASCII(String input, boolean allowUnassigned, boolean useSTD3ASCIIRules) 68 throws IDNAException { 69 72 boolean nonASCII = false; 73 74 for (int i = 0; i < input.length(); i++) { 75 int c = input.charAt(i); 76 if (c > 0x7f) { 77 nonASCII = true; 78 break; 79 } 80 } 81 82 84 if (nonASCII) { 85 try { 86 input = Stringprep.nameprep(input, allowUnassigned); 87 } catch (StringprepException e) { 88 throw new IDNAException(e); 89 } 90 } 91 92 98 if (useSTD3ASCIIRules) { 99 for (int i = 0; i < input.length(); i++) { 100 int c = input.charAt(i); 101 if ((c <= 0x2c) || 102 (c >= 0x2e && c <= 0x2f) || 103 (c >= 0x3a && c <= 0x40) || 104 (c >= 0x5b && c <= 0x60) || 105 (c >= 0x7b && c <= 0x7f)) { 106 throw new IDNAException(IDNAException.CONTAINS_NON_LDH); 107 } 108 } 109 110 if (input.startsWith("-") || input.endsWith("-")) { 111 throw new IDNAException(IDNAException.CONTAINS_HYPHEN); 112 } 113 } 114 115 117 nonASCII = false; 118 119 for (int i = 0; i < input.length(); i++) { 120 int c = input.charAt(i); 121 if (c > 0x7f) { 122 nonASCII = true; 123 break; 124 } 125 } 126 127 String output = input; 128 129 if (nonASCII) { 130 131 133 if (input.startsWith(ACE_PREFIX)) { 134 throw new IDNAException(IDNAException.CONTAINS_ACE_PREFIX); 135 } 136 137 139 try { 140 output = Punycode.encode(input); 141 } catch (PunycodeException e) { 142 throw new IDNAException(e); 143 } 144 145 147 output = ACE_PREFIX + output; 148 } 149 150 152 if (output.length() < 1 || output.length() > 63) { 153 throw new IDNAException(IDNAException.TOO_LONG); 154 } 155 156 return output; 157 } 158 159 167 public static String toUnicode(String input) { 168 StringBuilder o = new StringBuilder (); 169 StringBuilder h = new StringBuilder (); 170 171 for (int i = 0; i < input.length(); i++) { 172 char c = input.charAt(i); 173 if (c == '.' || c == '\u3002' || c == '\uff0e' || c == '\uff61') { 174 o.append(toUnicode(h.toString(), false, true)); 175 o.append(c); 176 h = new StringBuilder (); 177 } else { 178 h.append(c); 179 } 180 } 181 o.append(toUnicode(h.toString(), false, true)); 182 return o.toString(); 183 } 184 185 193 public static String toUnicode(String input, boolean allowUnassigned, boolean useSTD3ASCIIRules) { 194 String original = input; 195 boolean nonASCII = false; 196 197 199 for (int i = 0; i < input.length(); i++) { 200 int c = input.charAt(i); 201 if (c > 0x7f) { 202 nonASCII = true; 203 break; 204 } 205 } 206 207 209 if (nonASCII) { 210 try { 211 input = Stringprep.nameprep(input, allowUnassigned); 212 } catch (StringprepException e) { 213 return original; 215 } 216 } 217 218 220 if (!input.startsWith(ACE_PREFIX)) { 221 return original; 223 } 224 225 String stored = input; 226 227 229 input = input.substring(ACE_PREFIX.length()); 230 231 233 String output; 234 235 try { 236 output = Punycode.decode(input); 237 } catch (PunycodeException e) { 238 return original; 240 } 241 242 244 String ascii; 245 246 try { 247 ascii = toASCII(output, allowUnassigned, useSTD3ASCIIRules); 248 } catch (IDNAException e) { 249 return original; 251 } 252 253 255 if (!ascii.equalsIgnoreCase(stored)) { 256 return original; 258 } 259 260 262 return output; 263 } 264 } | Popular Tags |