• 粗糙的识别搜索引擎关键字编码类型


    这里所说的搜索引擎主要是Google,因为像百度这种搜索引擎,老老实实的只使用GB2312编码,自然不存在识别的问题。而Google本来也很厚道的会在Url中标识一下关键词的编码类型,可惜得加一个修饰“有时”,而另外一些时候,它会十分体贴的自动识别转化而不告诉你……

    本着“Google可往,我亦可往”的信念,自己动手解决关键字编码自动识别的问题。

    好在需要识别的范围已经限定了:GB2312 or UTF-8。那么当然要从了解这两种编码的编码格式下手。网上资源很多,摘其精华。

    两种编码的格式限定:

    GB2312:

    每个汉字及符号以两个字节来表示。第一个字节称为“高位字节”,第二个字节称为“低位字节”。
    “高位字节”使用了0xA1-0xF7(把01-87区的区号加上0xA0),“低位字节”使用了0xA1-0xFE(把01-94加上0xA0)。

    UTF-8:

    UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。UTF-8最多可用到6个字节。
    如表:
    1字节 0xxxxxxx
    2字节 110xxxxx 10xxxxxx
    3字节 1110xxxx 10xxxxxx 10xxxxxx
    4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

    而在UTF-8中,汉字都是采用3字节编码的,即首位为1110xxxx,其余两位为10xxxxxx。

    考虑UTF-8和Unicode的汉字编码转换关系:将Unicode的两字节二进制编码拆成4、6、6位,分别插入模板1110xxxx 10xxxxxx 10xxxxxx 中,即为对应的UTF-8汉字编码。

    例如“汉”字的Unicode编码是6C49。将6C49的二进制:0110 110001 001001, 放入模板中,得到:11100110 10110001 10001001,即E6 B1 89。

    而Unicode中的汉字编码范围为4E00~9FA5(参见http://www.chi2ko.com/tool/CJK.htm)

    那么相对应的UTF-8的范围是E4A880~E9BEA5

    下面再简单看下经过URL编码后的两种编码格式的结果:

    “博客”:

    • UTF-8编码(16进制):E58D9A E5AEA2
    • UTF-8 + Url编码:%E5%8D%9A%E5%AE%A2
    • GB2312编码:B2A9 BFCD
    • GB2312 + Url编码:%B2%A9%BF%CD

    结论很清楚,Url编码就是在两种编码格式的16进制基础上拆分每个字节并加上‘%’前缀

    自动识别的思路:

    那么基于以上的成果,可以找出UTF-8和GB2312在URL编码后的特点和不同,为了说明方便,这里称形如’%xx ’的URL部分为一小节,考察一段纯汉字关键词,会得出以下结论。

    1. UTF-8格式的小节数为3的倍数,而GB2312的小节数为2的倍数。
    2. UTF-8格式的每小节首位为89AB,而GB2312得每小节首位为A-F。
    3. UTF-8格式的每个字被划为三小节,且第一小节的首位为E,次位为4~9。

    那么考虑如下自动识别的思路:先获取URL中所有的小节数x,然后获取所有以E开头的每三小节数y,比较x与3y,如果两者不相等,则说明不是UTF-8编码。

    这里注意,考虑到一些特殊符号同样会被Url编码成“%xx ”的形式,比如‘%’会被编码成“%25”,所以每小节的特征应当是首位>=7。

    解决方法:

    其实最终解决方法就是两条正则表达式:

    String utfRegexPattern = @"(%e[4-9])(%[89ab][0-9a-f]){2}";
    String regexPattern = "(%[89a-f][0-9a-f])";
    MatchCollection utfMatches = Regex.Matches(url, utfRegexPattern);
    MatchCollection matches = Regex.Matches(url, regexPattern);
    if (matches.Count != utfMatches.Count * 3)
    {
        encoding = Encoding.GetEncoding("GB2312");
    }

    第一条正则匹配符合Utf-8编码特征的每三小节,而第二条则匹配每一小节。

    注:

    这种方法只能判断一串url不是Utf-8编码,但不能确定一串编码是utf-8编码,比如:%E5%B0%B4%E6%B4%B0,可以是 GB2312的“灏存窗”,也可以是utf-8的“尴洰”,应用上述方法并不能判断它到底是哪种编码格式。google将其识别为了utf-8格式:

    http://www.google.cn/search?hl=zh-CN&q=%E5%B0%B4%E6%B4%B0

    但Google也有识别失误的时候:

    http://www.google.cn/search?hl=zh-CN&q=%D1%A7%CF%B0

    %D1%A7%CF%B0是GB2312编码的“学习”,但被Google判断为Utf-8格式。而用上述方法可以进行识别。

    也许Google是利用字符集做匹配判断的?Who knows?

  • 相关阅读:
    基于visual Studio2013解决C语言竞赛题之0407最大值最小值
    基于visual Studio2013解决C语言竞赛题之0406数列求和
    基于visual Studio2013解决C语言竞赛题之0405阶乘求和
    基于visual Studio2013解决C语言竞赛题之0404循环求和
    基于visual Studio2013解决C语言竞赛题之0403字符统计
    基于visual Studio2013解决C语言竞赛题之0402奇偶求和
    基于visual Studio2013解决C语言竞赛题之0401阶乘
    当当网首页——html代码
    当当网首页——html代码
    当当网首页——html代码
  • 原文地址:https://www.cnblogs.com/zxktxj/p/2758250.html
Copyright © 2020-2023  润新知