http://www.sufeinet.com/plugin.php?id=keke_group

苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 6148|回复: 1

[站长工具] C#实现中文域名搜索引擎编码/解码-PunyCode编码与解码

[复制链接]
发表于 2019-11-18 16:31:03 | 显示全部楼层 |阅读模式
C#实现中文域名搜索引擎编码/解码-PunyCode编码与解码


大家都知道白底收录 的中文域名为转为为xn--开头的字符串。

这个是怎么实现 的呢,我们先来分析一下原理

先来科普个知识
[C#] 纯文本查看 复制代码
Punycode是一个根据RFC 3492标准而制定的编码系统,主要用於把域名从地方语言所采用的Unicode编码转换成为可用於DNS系统的编码。Punycode可以防止IDN欺骗。

国际化域名IDNs 

 
早期的DNS(Domain Name System)是只支持英文域名解析。在IDNs(国际化域名Internationalized Domain Names)推出以后,

为了保证兼容以前的DNS,所以,对IDNs进行punycode转码,转码后的punycode就由26个字母+10个数字,还有“-”组成。

浏览器对punycode的支持    

目前,因为操作系统的核心都是英文组成,DNS服务器的解析也是由英文代码交换,所以DNS服务器上并不支持直接的中文域名解析,

所有中文域名的解析都需要转成punycode码,然后由DNS解析punycode码。其实目前所说和各种浏览器完美支持中文域名,

只是浏览器软里面主动加入了中文域名自动转码,不需要原来的再次安装中文域名转码控件来完成整个流程。

完全免费,双向转换 中文域名转码就是将中文字符串转成punycode标准编码的字符串。

本服务目前支持GBK,GB2312编码和punycode编码的相互转换。

域名串不允许有除“-”以外的标点符号,包括空格。 可以夹杂中文和英文。 可以输入全角英文字母,全角字母不区分大小写。


具体怎么实现呢,大家直接看帮助类
[C#] 纯文本查看 复制代码
 public class PunyCodeHelper
    {
        /* 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 = '-';
        public static string EncodingDomain(string domain)
        {
            domain = domain.Replace("。", ".");
            string[] domainArray = domain.Split(new string[] { "." }, StringSplitOptions.None);
            string result = "";
            foreach (string item in domainArray)
            {
                if (item == "")
                {
                    result += ".";
                    continue;
                }
                result += "xn--" + Encode(item) + ".";
            }
            if (result[result.Length - 1] == '.') result = result.Substring(0, result.Length - 1);
            return result;
        }
        public static string DecodingDomain(string domain)
        {
            domain = domain.Replace("。", ".");
            string[] domainArray = domain.Split(new string[] { "." }, StringSplitOptions.None);
            string result = "";
            foreach (string item in domainArray)
            {
                if (item == "")
                {
                    result += ".";
                    continue;
                }
                string item2 = item;
                if (item2.Length > 4 && item2.Substring(0, 4) == "xn--")
                {
                    result += Decode(item2.Substring(4, item2.Length - 4)) + ".";
                }
            }
            if (result[result.Length - 1] == '.') result = result.Substring(0, result.Length - 1);
            return result;
        }
        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();
        }
        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();
        }
        private 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);
        }
        private static bool isBasic(char c)
        {
            return c < 0x80;
        }
        private 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");
            }
        }
        private 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");
            }
        }
    }


然后直接在页面下这样写即可
[C#] 纯文本查看 复制代码
  //e是编码,d是解码
                    type = InputHelper.GetInputString(Request["type"]).Trim();
                    //传过来的数据
                    key = InputHelper.GetInputString(Request["key"]).Trim();
                    if (type == "e")
                    {
                        html = key;
                        foreach (Match item in Regex.Matches(html, "([\u4e00-\u9fa5]+)", RegexOptions.IgnoreCase | RegexOptions.Compiled))
                        {
                            html = Regex.Replace(html, item.Groups[1].Value.Trim(), PunyCodeHelper.EncodingDomain(item.Groups[1].Value.Trim()), RegexOptions.IgnoreCase | RegexOptions.Compiled);
                        }
                       
                    }
                    else if (type == "d")
                    {
                        html = key;
                        foreach (Match item in Regex.Matches(html, "(xn--\\w+)", RegexOptions.IgnoreCase | RegexOptions.Compiled))
                        {
                            html = Regex.Replace(html, item.Groups[1].Value.Trim(), PunyCodeHelper.DecodingDomain(item.Groups[1].Value.Trim()), RegexOptions.IgnoreCase | RegexOptions.Compiled);
                        }
                    }

在线测试效果。https://seo.ruituoyun.com/punycode   





1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
 楼主| 发表于 2019-11-18 16:32:37 | 显示全部楼层

例子看看这个域名的编码结果
http://www.涵金爱美.com
如下直接单击查看
https://seo.ruituoyun.com/punyco ... E%8E.com&type=e

您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2024-3-29 15:40

© 2014-2021

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