1 28 29 package com.caucho.server.host; 30 31 import com.caucho.log.Log; 32 import com.caucho.util.CharBuffer; 33 import com.caucho.util.L10N; 34 35 import java.util.logging.Level ; 36 import java.util.logging.Logger ; 37 38 39 42 public class DomainName { 43 static final Logger log = Log.open(DomainName.class); 44 static final L10N L = new L10N(DomainName.class); 45 46 private final static char ENCODE[]; 47 private final static int DECODE[]; 48 49 private final static int base = 36; 50 private final static int tmin = 1; 51 private final static int tmax = 26; 52 private final static int skew = 38; 53 private final static int damp = 700; 54 private final static int initialBias = 72; 55 private final static int initialN = 128; 56 57 60 public static String fromAscii(String source) 61 { 62 CharBuffer result = CharBuffer.allocate(); 63 CharBuffer cb = CharBuffer.allocate(); 64 65 int index = 0; 66 int length = source.length(); 67 boolean isFirst = true; 68 69 try { 70 while (index < length) { 71 char ch = source.charAt(index + 0); 72 73 if (isFirst && index + 4 < length && 74 source.charAt(index + 0) == 'x' && 75 source.charAt(index + 1) == 'n' && 76 source.charAt(index + 2) == '-' && 77 source.charAt(index + 3) == '-') { 78 int p = source.indexOf('.', index); 79 String seq; 80 81 if (p < 0) 82 seq = source.substring(index + 4); 83 else 84 seq = source.substring(index + 4, p); 85 86 decode(result, cb, seq); 87 88 index += 4 + seq.length(); 89 continue; 90 } 91 92 index++; 93 94 isFirst = false; 95 96 if (ch == '.') { 97 isFirst = true; 98 99 result.append(ch); 100 } 101 else 102 result.append(Character.toLowerCase(ch)); 103 } 104 105 return result.close(); 106 } catch (Throwable e) { 107 log.log(Level.WARNING, e.toString(), e); 108 109 throw new RuntimeException (e); 110 } 111 } 112 113 116 public static String toAscii(String source) 117 { 118 CharBuffer result = CharBuffer.allocate(); 119 CharBuffer cb = CharBuffer.allocate(); 120 121 int head = 0; 122 int length = source.length(); 123 124 while (head < length) { 125 boolean isAscii = true; 126 127 cb.clear(); 128 129 int i = head; 130 for (; i < length; i++) { 131 char ch = source.charAt(i); 132 133 if (ch == '.') { 134 cb.append(ch); 135 break; 136 } 137 else if (ch <= 0x7f) 138 cb.append(ch); 139 else { 140 isAscii = false; 141 break; 142 } 143 } 144 145 if (isAscii) { 146 head = i + 1; 147 result.append(cb); 148 continue; 149 } 150 151 cb.clear(); 152 i = head; 153 for (; i < length; i++) { 154 char ch = source.charAt(i); 155 156 if (ch == '.') 157 break; 158 159 cb.append(ch); 161 } 162 head = i; 163 164 String seq = cb.toString(); 165 166 cb.clear(); 167 168 toAscii(cb, seq); 169 170 result.append(cb); 171 } 172 173 return result.close(); 174 } 175 176 private static void decode(CharBuffer result, CharBuffer cb, String seq) 177 { 178 int length = seq.length(); 179 int b = 0; 180 181 for (int i = 0; i < length; i++) { 182 char ch = seq.charAt(i); 183 184 if (ch == '-') 185 b = i; 186 } 187 188 for (int i = 0; i < b; i++) { 189 char ch = seq.charAt(i); 190 191 cb.append(Character.toLowerCase(ch)); 192 } 193 194 int in = b > 0 ? b + 1 : 0; 195 int i = 0; 196 int bias = initialBias; 197 int out = cb.length(); 198 int n = initialN; 199 200 while (in < length) { 201 int oldi = i; 202 int w = 1; 203 204 for (int k = base; true; k += base) { 205 char ch = seq.charAt(in++); 206 int digit = DECODE[ch]; 207 208 i += digit * w; 209 210 int t; 211 if (k <= bias) 212 t = tmin; 213 else if (bias + tmax <= k) 214 t = tmax; 215 else 216 t = k - bias; 217 218 if (digit < t) 219 break; 220 221 w *= (base - t); 222 } 223 224 bias = adapt(i - oldi, out + 1, oldi == 0); 225 226 n += i / (out + 1); 227 i %= (out + 1); 228 229 cb.append(' '); 230 char []cBuf = cb.getBuffer(); 231 232 System.arraycopy(cBuf, i, cBuf, i + 1, out - i); 233 cBuf[i++] = Character.toLowerCase((char) n); 234 235 out++; 236 } 237 238 result.append(cb); 239 } 240 241 private static void toAscii(CharBuffer cb, String seq) 242 { 243 cb.append("xn--"); 244 245 int length = seq.length(); 246 247 int index = 0; 248 int n = initialN; 249 int delta = 0; 250 int bias = initialBias; 251 int b = 0; 253 for (int i = 0; i < length; i++) { 254 char ch = seq.charAt(i); 255 if (ch < 0x80) { 256 cb.append(ch); 257 b++; 258 } 259 } 260 261 if (b > 0) 262 cb.append('-'); 263 264 int h = b; 265 266 while (h < length) { 267 int m = 0xffff; 268 269 for (int i = 0; i < length; i++) { 270 char ch = seq.charAt(i); 271 272 if (n <= ch && ch < m) 273 m = ch; 274 } 275 276 delta = delta + (m - n) * (h + 1); 278 n = m; 279 280 for (int i = 0; i < length; i++) { 281 int ch = seq.charAt(i); 282 283 if (ch < n) { 284 delta++; 285 } 286 287 if (ch == n) { 288 int q = delta; 289 290 for (int k = base; true; k += base) { 291 int t; 292 293 if (k <= bias) 294 t = tmin; 295 else if (bias + tmax <= k) 296 t = tmax; 297 else 298 t = k - bias; 299 300 if (q < t) 301 break; 302 303 cb.append(ENCODE[t + (q - t) % (base - t)]); 304 q = (q - t) / (base - t); 305 } 306 307 cb.append(ENCODE[q]); 308 bias = adapt(delta, h + 1, h == b); 309 delta = 0; 310 h++; 311 } 312 } 313 314 delta++; 315 n++; 316 } 317 } 318 319 private static int adapt(int delta, int nPoints, boolean isFirst) 320 { 321 int k; 322 323 delta = isFirst ? delta / damp : delta / 2; 324 delta += delta / nPoints; 325 326 for (k = 0; ((base - tmin) * tmax) / 2 < delta; k += base) { 327 delta /= base - tmin; 328 } 329 330 return k + (base - tmin + 1) * delta / (delta + skew); 331 } 332 333 static { 334 ENCODE = new char[36]; 335 336 for (int i = 0; i < 26; i++) { 337 ENCODE[i] = (char) ('a' + i); 338 } 339 340 for (int i = 0; i < 10; i++) { 341 ENCODE[i + 26] = (char) ('0' + i); 342 } 343 344 DECODE = new int[0x80]; 345 346 for (int i = 0; i < 26; i++) { 347 DECODE[(char) ('a' + i)] = i; 348 DECODE[(char) ('A' + i)] = i; 349 } 350 351 for (int i = 0; i < 10; i++) { 352 DECODE[(char) ('0' + i)] = 26 + i; 353 } 354 } 355 } 356 | Popular Tags |