﻿{"id":1766,"date":"2012-02-07T13:55:28","date_gmt":"2012-02-07T05:55:28","guid":{"rendered":"http:\/\/blog.jixin.ntxz.net\/?p=1766"},"modified":"2012-02-07T13:55:28","modified_gmt":"2012-02-07T05:55:28","slug":"%e4%bd%bf%e7%94%a8c%e8%bf%9b%e8%a1%8cpunycode%e7%bc%96%e7%a0%81%e4%b8%ad%e6%96%87%e5%9f%9f%e5%90%8d%e7%9a%84%e4%bb%a3%e7%a0%81","status":"publish","type":"post","link":"http:\/\/www.ntxz.net\/?p=1766","title":{"rendered":"\u4f7f\u7528C#\u8fdb\u884cPunycode\u7f16\u7801\u4e2d\u6587\u57df\u540d\u7684\u4ee3\u7801"},"content":{"rendered":"<p><strong>\u6d4b\u8bd5\uff1a<\/strong><\/p>\n<p>string s = Punycode.EncodingDomain(&#8220;\u4e2d\u56fd.\u9999\u6e2f&#8221;);<\/p>\n<p>Console.WriteLine(s);<\/p>\n<p>Console.WriteLine(Punycode.DecodingDomain(s));<\/p>\n<pre class=\"brush: c#\">\r\n\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Text;\r\nusing System.Runtime.InteropServices;\r\nnamespace Domain.Text\r\n{\r\n    \/\/\/ &lt;summary&gt;\r\n    \/\/\/ Punycode IDN\u7f16\u7801\u64cd\u4f5c\r\n    \/\/\/ &lt;\/summary&gt;\r\n    public class Punycode\r\n    {\r\n        \/* Punycode parameters *\/\r\n        static int TMIN = 1;\r\n        static int TMAX = 26;\r\n        static int BASE = 36;\r\n        static int INITIAL_N = 128;\r\n        static int INITIAL_BIAS = 72;\r\n        static int DAMP = 700;\r\n        static int SKEW = 38;\r\n        static char DELIMITER = &#039;-&#039;;\r\n        public static string EncodingDomain(string domain)\r\n        {\r\n            domain = domain.Replace(&quot;\u3002&quot;, &quot;.&quot;);\r\n            string[] domainArray = domain.Split(new string[] { &quot;.&quot; }, StringSplitOptions.None);\r\n            string result = &quot;&quot;;\r\n            foreach (string item in domainArray)\r\n            {\r\n                if (item == &quot;&quot;)\r\n                {\r\n                    result += &quot;.&quot;;\r\n                    continue;\r\n                }\r\n                result += &quot;xn--&quot; + Encode(item) + &quot;.&quot;;\r\n            }\r\n            if (result[result.Length - 1] == &#039;.&#039;) result = result.Substring(0, result.Length - 1);\r\n            return result;\r\n        }\r\n        public static string DecodingDomain(string domain)\r\n        {\r\n            domain = domain.Replace(&quot;\u3002&quot;, &quot;.&quot;);\r\n            string[] domainArray = domain.Split(new string[] { &quot;.&quot; }, StringSplitOptions.None);\r\n            string result = &quot;&quot;;\r\n            foreach (string item in domainArray)\r\n            {\r\n                if (item == &quot;&quot;)\r\n                {\r\n                    result += &quot;.&quot;;\r\n                    continue;\r\n                }\r\n                string item2 = item;\r\n                if (item2.Length &gt; 4 &amp;&amp; item2.Substring(0, 4) == &quot;xn--&quot;)\r\n                {\r\n                    result += Decode(item2.Substring(4, item2.Length - 4)) + &quot;.&quot;;\r\n                }\r\n            }\r\n            if (result[result.Length - 1] == &#039;.&#039;) result = result.Substring(0, result.Length - 1);\r\n            return result;\r\n        }\r\n        public static string Encode(string input)\r\n        {\r\n            int n = INITIAL_N;\r\n            int delta = 0;\r\n            int bias = INITIAL_BIAS;\r\n            StringBuilder output = new StringBuilder();\r\n            \/\/ Copy all basic code points to the output\r\n            int b = 0;\r\n            for (int i = 0; i &lt; input.Length; i++)\r\n            {\r\n                char c = input[i];\r\n                if (isBasic(c))\r\n                {\r\n                    output.Append(c);\r\n                    b++;\r\n                }\r\n            }\r\n            \/\/ Append delimiter\r\n            if (b &gt; 0)\r\n            {\r\n                output.Append(DELIMITER);\r\n            }\r\n            int h = b;\r\n            while (h &lt; input.Length)\r\n            {\r\n                int m = int.MaxValue;\r\n                \/\/ Find the minimum code point &gt;= n\r\n                for (int i = 0; i &lt; input.Length; i++)\r\n                {\r\n                    int c = input[i];\r\n                    if (c &gt;= n &amp;&amp; c &lt; m)\r\n                    {\r\n                        m = c;\r\n                    }\r\n                }\r\n                if (m - n &gt; (int.MaxValue - delta) \/ (h + 1))\r\n                {\r\n                    throw new Exception(&quot;OVERFLOW&quot;);\r\n                }\r\n                delta = delta + (m - n) * (h + 1);\r\n                n = m;\r\n                for (int j = 0; j &lt; input.Length; j++)\r\n                {\r\n                    int c = input[j];\r\n                    if (c &lt; n)\r\n                    {\r\n                        delta++;\r\n                        if (0 == delta)\r\n                        {\r\n                            throw new Exception(&quot;OVERFLOW&quot;);\r\n                        }\r\n                    }\r\n                    if (c == n)\r\n                    {\r\n                        int q = delta;\r\n                        for (int k = BASE; ; k += BASE)\r\n                        {\r\n                            int t;\r\n                            if (k &lt;= bias)\r\n                            {\r\n                                t = TMIN;\r\n                            }\r\n                            else if (k &gt;= bias + TMAX)\r\n                            {\r\n                                t = TMAX;\r\n                            }\r\n                            else\r\n                            {\r\n                                t = k - bias;\r\n                            }\r\n                            if (q &lt; t)\r\n                            {\r\n                                break;\r\n                            }\r\n                            output.Append((char)digit2codepoint(t + (q - t) % (BASE - t)));\r\n                            q = (q - t) \/ (BASE - t);\r\n                        }\r\n                        output.Append((char)digit2codepoint(q));\r\n                        bias = adapt(delta, h + 1, h == b);\r\n                        delta = 0;\r\n                        h++;\r\n                    }\r\n                }\r\n                delta++;\r\n                n++;\r\n            }\r\n            return output.ToString();\r\n        }\r\n        public static string Decode(string input)\r\n        {\r\n            int n = INITIAL_N;\r\n            int i = 0;\r\n            int bias = INITIAL_BIAS;\r\n            StringBuilder output = new StringBuilder();\r\n            int d = input.LastIndexOf(DELIMITER);\r\n            if (d &gt; 0)\r\n            {\r\n                for (int j = 0; j &lt; d; j++)\r\n                {\r\n                    char c = input[j];\r\n                    if (!isBasic(c))\r\n                    {\r\n                        throw new Exception(&quot;BAD_INPUT&quot;);\r\n                    }\r\n                    output.Append(c);\r\n                }\r\n                d++;\r\n            }\r\n            else\r\n            {\r\n                d = 0;\r\n            }\r\n            while (d &lt; input.Length)\r\n            {\r\n                int oldi = i;\r\n                int w = 1;\r\n                for (int k = BASE; ; k += BASE)\r\n                {\r\n                    if (d == input.Length)\r\n                    {\r\n                        throw new Exception(&quot;BAD_INPUT&quot;);\r\n                    }\r\n                    int c = input[d++];\r\n                    int digit = codepoint2digit(c);\r\n                    if (digit &gt; (int.MaxValue - i) \/ w)\r\n                    {\r\n                        throw new Exception(&quot;OVERFLOW&quot;);\r\n                    }\r\n                    i = i + digit * w;\r\n                    int t;\r\n                    if (k &lt;= bias)\r\n                    {\r\n                        t = TMIN;\r\n                    }\r\n                    else if (k &gt;= bias + TMAX)\r\n                    {\r\n                        t = TMAX;\r\n                    }\r\n                    else\r\n                    {\r\n                        t = k - bias;\r\n                    }\r\n                    if (digit &lt; t)\r\n                    {\r\n                        break;\r\n                    }\r\n                    w = w * (BASE - t);\r\n                }\r\n                bias = adapt(i - oldi, output.Length + 1, oldi == 0);\r\n                if (i \/ (output.Length + 1) &gt; int.MaxValue - n)\r\n                {\r\n                    throw new Exception(&quot;OVERFLOW&quot;);\r\n                }\r\n                n = n + i \/ (output.Length + 1);\r\n                i = i % (output.Length + 1);\r\n                output.Insert(i, (char)n);\r\n                i++;\r\n            }\r\n            return output.ToString();\r\n        }\r\n        private static int adapt(int delta, int numpoints, bool first)\r\n        {\r\n            if (first)\r\n            {\r\n                delta = delta \/ DAMP;\r\n            }\r\n            else\r\n            {\r\n                delta = delta \/ 2;\r\n            }\r\n            delta = delta + (delta \/ numpoints);\r\n            int k = 0;\r\n            while (delta &gt; ((BASE - TMIN) * TMAX) \/ 2)\r\n            {\r\n                delta = delta \/ (BASE - TMIN);\r\n                k = k + BASE;\r\n            }\r\n            return k + ((BASE - TMIN + 1) * delta) \/ (delta + SKEW);\r\n        }\r\n        private static bool isBasic(char c)\r\n        {\r\n            return c &lt; 0x80;\r\n        }\r\n        private static int digit2codepoint(int d)\r\n        {\r\n            if (d &lt; 26)\r\n            {\r\n                \/\/ 0..25 : &#039;a&#039;..&#039;z&#039;\r\n                return d + &#039;a&#039;;\r\n            }\r\n            else if (d &lt; 36)\r\n            {\r\n                \/\/ 26..35 : &#039;0&#039;..&#039;9&#039;;\r\n                return d - 26 + &#039;0&#039;;\r\n            }\r\n            else\r\n            {\r\n                throw new Exception(&quot;BAD_INPUT&quot;);\r\n            }\r\n        }\r\n        private static int codepoint2digit(int c)\r\n        {\r\n            if (c - &#039;0&#039; &lt; 10)\r\n            {\r\n                \/\/ &#039;0&#039;..&#039;9&#039; : 26..35\r\n                return c - &#039;0&#039; + 26;\r\n            }\r\n            else if (c - &#039;a&#039; &lt; 26)\r\n            {\r\n                \/\/ &#039;a&#039;..&#039;z&#039; : 0..25\r\n                return c - &#039;a&#039;;\r\n            }\r\n            else\r\n            {\r\n                throw new Exception(&quot;BAD_INPUT&quot;);\r\n            }\r\n        }\r\n    }\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u6d4b\u8bd5\uff1a string s = Punycode.EncodingDomain(&#8220;\u4e2d\u56fd.\u9999\u6e2f&#038;#82 [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,7],"tags":[497,498],"class_list":["post-1766","post","type-post","status-publish","format-standard","hentry","category-csharp","category-fromnetwork","tag-497","tag-498"],"views":1168,"_links":{"self":[{"href":"http:\/\/www.ntxz.net\/index.php?rest_route=\/wp\/v2\/posts\/1766","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.ntxz.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.ntxz.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.ntxz.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.ntxz.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1766"}],"version-history":[{"count":1,"href":"http:\/\/www.ntxz.net\/index.php?rest_route=\/wp\/v2\/posts\/1766\/revisions"}],"predecessor-version":[{"id":1767,"href":"http:\/\/www.ntxz.net\/index.php?rest_route=\/wp\/v2\/posts\/1766\/revisions\/1767"}],"wp:attachment":[{"href":"http:\/\/www.ntxz.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1766"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.ntxz.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1766"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.ntxz.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1766"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}