测试代码
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 ( ) ;
}
}