六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 31|回复: 0

punycode和中文相互转换

[复制链接]

升级  85%

884

主题

884

主题

884

主题

探花

Rank: 6Rank: 6

积分
2700
 楼主| 发表于 2013-1-26 14:19:44 | 显示全部楼层 |阅读模式
问题来自论坛,google了一下有java的版本,随手翻译了一下,测试没有问题
java代码来自
http://www.koders.com/java/fidA5FC1F237C9D005FD1BAD91769F8CF107601BA28.aspx
感谢原作者
using System;using System.Collections.Generic;using System.Text;using System.Runtime.InteropServices;namespace ConsoleApplication9{    class Program    {        static void Main(string[] args)        {            string strPunycode ="xn--"+ Punycode.encode("近身剪");            //xn--ferv28lgza            string strChinese = Punycode.decode("ferv28lgza");            //近身剪        }    }    class Punycode    {        /* Punycode parameters */        static int TMIN = 1;        static int TMAX = 26;        static int BASE = 36;        static int INITIAL_N = 128;        static int INITIAL_BIAS = 72;        static int DAMP = 700;        static int SKEW = 38;        static char DELIMITER = '-';        /**         * Punycodes a unicode string.         *         * @param input Unicode string.         * @return Punycoded string.         */        public static String encode(String input)        {            int n = INITIAL_N;            int delta = 0;            int bias = INITIAL_BIAS;            StringBuilder output = new StringBuilder();            // Copy all basic code points to the output            int b = 0;            for (int i = 0; i < input.Length; i++)            {                char c = input[i];                if (isBasic(c))                {                    output.Append(c);                    b++;                }            }            // Append delimiter            if (b > 0)            {                output.Append(DELIMITER);            }            int h = b;            while (h < input.Length)            {                int m = int.MaxValue;                // Find the minimum code point >= n                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("OVERFLOW");                }                delta = 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("OVERFLOW");                        }                    }                    if (c == n)                    {                        int q = delta;                        for (int k = BASE; ; k += BASE)                        {                            int t;                            if (k <= bias)                            {                                t = TMIN;                            }                            else if (k >= bias + TMAX)                            {                                t = TMAX;                            }                            else                            {                                t = k - bias;                            }                            if (q < t)                            {                                break;                            }                            output.Append((char)digit2codepoint(t + (q - t) % (BASE - t)));                            q = (q - t) / (BASE - t);                        }                        output.Append((char)digit2codepoint(q));                        bias = adapt(delta, h + 1, h == b);                        delta = 0;                        h++;                    }                }                delta++;                n++;            }            return output.ToString();        }        /**         * Decode a punycoded string.         *         * @param input Punycode string         * @return Unicode string.         */        public static String decode(String input)        {            int n = INITIAL_N;            int i = 0;            int bias = INITIAL_BIAS;            StringBuilder output = new StringBuilder();            int d = input.LastIndexOf(DELIMITER);            if (d > 0)            {                for (int j = 0; j < d; j++)                {                    char c = input[j];                    if (!isBasic(c))                    {                        throw new Exception("BAD_INPUT");                    }                    output.Append(c);                }                d++;            }            else            {                d = 0;            }            while (d < input.Length)            {                int oldi = i;                int w = 1;                for (int k = BASE; ; k += BASE)                {                    if (d == input.Length)                    {                        throw new Exception("BAD_INPUT");                    }                    int c = input[d++];                    int digit = codepoint2digit(c);                    if (digit > (int.MaxValue - i) / w)                    {                        throw new Exception("OVERFLOW");                    }                    i = i + digit * w;                    int t;                    if (k <= bias)                    {                        t = TMIN;                    }                    else if (k >= bias + TMAX)                    {                        t = TMAX;                    }                    else                    {                        t = k - bias;                    }                    if (digit < t)                    {                        break;                    }                    w = w * (BASE - t);                }                bias = adapt(i - oldi, output.Length + 1, oldi == 0);                if (i / (output.Length + 1) > int.MaxValue - n)                {                    throw new Exception("OVERFLOW");                }                n = n + i / (output.Length + 1);                i = i % (output.Length + 1);                output.Insert(i, (char)n);                i++;            }            return output.ToString();        }        public static int adapt(int delta, int numpoints, bool first)        {            if (first)            {                delta = delta / DAMP;            }            else            {                delta = delta / 2;            }            delta = delta + (delta / numpoints);            int k = 0;            while (delta > ((BASE - TMIN) * TMAX) / 2)            {                delta = delta / (BASE - TMIN);                k = k + BASE;            }            return k + ((BASE - TMIN + 1) * delta) / (delta + SKEW);        }        public static bool isBasic(char c)        {            return c < 0x80;        }        public static int digit2codepoint(int d)        {            if (d < 26)            {                // 0..25 : 'a'..'z'                return d + 'a';            }            else if (d < 36)            {                // 26..35 : '0'..'9';                return d - 26 + '0';            }            else            {                throw new Exception("BAD_INPUT");            }        }        public static int codepoint2digit(int c)        {            if (c - '0' < 10)            {                // '0'..'9' : 26..35                return c - '0' + 26;            }            else if (c - 'a' < 26)            {                // 'a'..'z' : 0..25                return c - 'a';            }            else            {                throw new Exception("BAD_INPUT");            }        }    }}
检查结果可以用以下网站工具
http://www.nicenic.com/domain/punycode.php
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表