これを移植した。
Punycode変換のコードを書いてみました - Operaの備忘録のぺえじ - チーム俺等
http://orera.g.hatena.ne.jp/misttrap/20080518/p1
jp/eth0/Punycode.as
package jp.eth0 { public class Punycode { protected static const BASE:int = 36; protected static const TMIN:int = 1; protected static const TMAX:int = 26; protected static const DAMP:int = 700; protected static const INITIAL_BIAS:int = 72; protected static const INITIAL_N:int = 0x80; protected static const DELIMITER:String = '-'; protected static const ENCODE_TABLE:Array = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ]; protected static const DECODE_TABLE:Object = { 'a' : 0, 'A' : 0, 'b' : 1, 'B' : 1, 'c' : 2, 'C' : 2, 'd' : 3, 'D' : 3, 'e' : 4, 'E' : 4, 'f' : 5, 'F' : 5, 'g' : 6, 'G' : 6, 'h' : 7, 'H' : 7, 'i' : 8, 'I' : 8, 'j' : 9, 'J' : 9, 'k' : 10, 'K' : 10, 'l' : 11, 'L' : 11, 'm' : 12, 'M' : 12, 'n' : 13, 'N' : 13, 'o' : 14, 'O' : 14, 'p' : 15, 'P' : 15, 'q' : 16, 'Q' : 16, 'r' : 17, 'R' : 17, 's' : 18, 'S' : 18, 't' : 19, 'T' : 19, 'u' : 20, 'U' : 20, 'v' : 21, 'V' : 21, 'w' : 22, 'W' : 22, 'x' : 23, 'X' : 23, 'y' : 24, 'Y' : 24, 'z' : 25, 'Z' : 25, '0' : 26, '1' : 27, '2' : 28, '3' : 29, '4' : 30, '5' : 31, '6' : 32, '7' : 33, '8' : 34, '9' : 35 }; /* bias offset */ protected static const ADAPT_DIV:int = BASE - TMIN; // 35 protected static const ADAPT_LIMIT:int = ADAPT_DIV * TMAX >> 1; // 455 protected static const ADAPT_TABLE:Array = [ // Math.floor((BASE - TMIN + 1) * delta / (delta + SKEW)) 0, 0, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 ]; protected static function adapt(delta:int, firstTime:Boolean, numPoints:int):int { var k:int; delta = firstTime ? (delta - delta % DAMP) / DAMP : (delta - (delta & 1) ) / 2; delta += (delta - delta % numPoints) / numPoints; for (k = 0; delta > ADAPT_LIMIT; k += BASE) delta = (delta - delta % ADAPT_DIV) / ADAPT_DIV; return k + ADAPT_TABLE[delta]; } /* decode */ public static function decode(input:String):String { var n:int = INITIAL_N; var i:int = 0; var bias:int = INITIAL_BIAS; var b:int = input.lastIndexOf(DELIMITER); var output:String = b > 0 ? input.substring(0, b) : ''; b++; var len:int = input.length, h:int = output.length, f:Function = String.fromCharCode; while (b < len) { var old_i:int = i, w:int = 1, k:int = BASE, kmax:int = bias + TMAX, digit:int, t:int; while ((i += (digit = DECODE_TABLE[input.charAt(b++)]) * w) && ( t = k <= bias ? TMIN : k >= kmax ? TMAX : k - bias ) <= digit) { w *= BASE - t; k += BASE; } bias = adapt(i - old_i, old_i == 0, ++h); n += (i - (i %= h)) / h; output = output.substring(0, i) + f(n) + output.substring(i++); } return output; } /* encode */ protected static function descend(a:int, b:int):int { return b - a; }; public static function encode(input:String):String { var n:int = INITIAL_N; var delta:int = 0; var bias:int = INITIAL_BIAS; var output:Array = []; var j:int = 0, len:int = input.length, b:int = 0, f:Function = String.fromCharCode, buf:Array = [], chk:Object = {}, ext:Array = [], c:int = 0; while (j < len) { var code:int = input.charCodeAt(j); code < n ? ( output[b++] = f(code), buf[j++] = 0 ) : chk.hasOwnProperty(code) ? ( buf[j++] = code ) : ( chk[buf[j++] = ext[c++] = code] = null ); } var h:int = b; if (b) output[b] = DELIMITER; for (ext.sort(descend); c; delta++, n++) { delta -= (n - (n = ext[--c])) * (h + 1); j = 0; do switch (buf[j]) { case 0 : delta++; break; case n : for (var q:int = delta, k:int = BASE, kmax:int = bias + TMAX, t:int; ( t = k <= bias ? TMIN : k >= kmax ? TMAX : k - bias ) <= q; k += BASE) { var div:int = BASE - t, mod:int = (q -= t) % div; output[output.length] = ENCODE_TABLE[t + mod]; q = (q - mod) / div; } output[output.length] = ENCODE_TABLE[q]; bias = adapt(delta, h == b, ++h); buf[j] = delta = 0; } while (++j < len); } return output.join(''); }; } }
punycode_test.mxml
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="100%" height="100%" xmlns:eth0="jp.eth0.*" backgroundGradientColors="[#ffffff, #cccccc]" > <mx:Script> <![CDATA[ import mx.utils.ObjectUtil; import jp.eth0.Punycode; public function decode():void { result.text = Punycode.decode(txt.text); } public function encode():void { result.text = Punycode.encode(txt.text); } ]]> </mx:Script> <mx:VBox> <mx:TextInput id="txt" /> <mx:Button label="Decode" click="{decode()}"/> <mx:Button label="Encode" click="{encode()}"/> <mx:TextInput id="result" /> </mx:VBox> </mx:Application>