测试代码
string word = "我爱你" ;
string idn = "我爱你.中国" ;
string wordCode = PunyCode. Encode ( word) ;
string punycode = PunyCode. IDN2Punycode ( idn) ; Console. WriteLine ( word) ;
Console. WriteLine ( wordCode) ;
Console. WriteLine ( PunyCode. Decode ( wordCode) ) ; Console. WriteLine ( ) ; Console. WriteLine ( idn) ;
Console. WriteLine ( punycode) ;
Console. WriteLine ( PunyCode. Punycode2IDN ( punycode) ) ;
输出
我爱你
6qq986b3xl
我爱你我爱你.中国
xn--6qq986b3xl.xn--fiqs8s
我爱你.中国
源码
using System ;
using System. Text ;
using System. Text. RegularExpressions ; public class PunyCode
{ public static string IDN2Punycode ( string input) { string [ ] spli = new string [ ] { "." } ; string [ ] inputArray = input. Split ( spli, StringSplitOptions. RemoveEmptyEntries) ; string retstr = "" ; for ( int i = 0 ; i < inputArray. Length; i++ ) { Regex myreg = new Regex ( "^[0-9a-zA-Z\\-]+$" ) ; if ( myreg. IsMatch ( inputArray[ i] ) ) retstr += inputArray[ i] + "." ; else retstr += "xn--" + Encode ( inputArray[ i] ) + "." ; } return retstr. TrimEnd ( '.' ) ; } public static string Punycode2IDN ( string input) { string [ ] spli = new string [ ] { "." } ; string [ ] inputArray = input. ToLower ( ) . Split ( spli, StringSplitOptions. RemoveEmptyEntries) ; string retstr = "" ; for ( int i = 0 ; i < inputArray. Length; i++ ) { string tmp = inputArray[ i] ; if ( tmp. StartsWith ( "xn--" ) ) retstr += Decode ( tmp. Substring ( 4 ) ) + "." ; else retstr += tmp + "." ; } return retstr. TrimEnd ( '.' ) ; } public static string Encode ( string input) { int n = 0x80 ; int delta = 0 ; int bias = 72 ; StringBuilder output = new StringBuilder ( ) ; int b = 0 ; for ( int i = 0 ; i < input. Length; i++ ) { char c = input[ i] ; if ( c < 0x80 ) { output. Append ( c) ; b++ ; } } if ( b > 0 ) output. Append ( '-' ) ; int h = b; while ( h < input. Length) { int m = int . MaxValue; for ( int i = 0 ; i < input. Length; i++ ) { int c = input[ i] ; if ( c >= n && c < m) m = c; } if ( m - n > ( int . MaxValue - delta) / ( h + 1 ) ) throw new Exception ( ) ; delta += ( m - n) * ( h + 1 ) ; n = m; for ( int j = 0 ; j < input. Length; j++ ) { int c = input[ j] ; if ( c < n) { delta++ ; if ( 0 == delta) throw new Exception ( ) ; } if ( c == n) { int q = delta; for ( int k = 36 ; ; k += 36 ) { int t; if ( k <= bias) t = 1 ; else if ( k >= bias + 26 ) t = 26 ; else t = k - bias; if ( q < t) break ; output. Append ( ( char ) Digit2Codepoint ( t + ( q - t) % ( 36 - t) ) ) ; q = ( q - t) / ( 36 - t) ; } output. Append ( ( char ) Digit2Codepoint ( q) ) ; bias = Adapt ( delta, h + 1 , h == b) ; delta = 0 ; h++ ; } } delta++ ; n++ ; } return output. ToString ( ) ; } public static string Decode ( string input) { int n = 0x80 ; int i = 0 ; int bias = 72 ; StringBuilder output = new StringBuilder ( ) ; int d = input. LastIndexOf ( '-' ) ; if ( d > 0 ) { for ( int j = 0 ; j < d; j++ ) { char c = input[ j] ; if ( c >= 0x80 ) throw new Exception ( ) ; output. Append ( c) ; } d++ ; } else d = 0 ; while ( d < input. Length) { int oldi = i; int w = 1 ; for ( int k = 36 ; ; k += 36 ) { if ( d == input. Length) throw new Exception ( ) ; int c = input[ d++ ] ; int digit = Codepoint2Digit ( c) ; if ( digit > ( int . MaxValue - i) / w) throw new Exception ( ) ; i += digit * w; int t; if ( k <= bias) t = 1 ; else if ( k >= bias + 26 ) t = 26 ; else t = k - bias; if ( digit < t) break ; w *= 36 - t; } bias = Adapt ( i - oldi, output. Length + 1 , oldi == 0 ) ; if ( i / ( output. Length + 1 ) > int . MaxValue - n) throw new Exception ( ) ; n += i / ( output. Length + 1 ) ; i %= output. Length + 1 ; output. Insert ( i, ( char ) n) ; i++ ; } return output. ToString ( ) ; } private static int Adapt ( int delta, int numpoints, bool first) { delta /= first ? 700 : 2 ; delta += delta / numpoints; int k = 0 ; while ( delta > 455 ) { delta /= 35 ; k += 36 ; } return k + ( 36 * delta) / ( delta + 38 ) ; } private static int Digit2Codepoint ( int d) { if ( d < 26 ) return d + 97 ; if ( d < 36 ) return d + 22 ; throw new Exception ( ) ; } private static int Codepoint2Digit ( int c) { if ( c < 58 ) return c - 22 ; if ( c < 123 ) return c - 97 ; throw new Exception ( ) ; }
}