`

字符集编码的识别(zz)

 
阅读更多

字符集编码的识别(zz)

 

读取文本文件或者接收字节流时需要搞清字符编码才能正确处理,编码识别错误是出现乱码的主要原因。理解编码识别方法之前建议阅读:常用字符集编码的概要特性(一)和常用字符集编码的概要特性(二)。

 

通过约定识别

为了接收字节流时能正确识别编码,很多情况下发送字节流的同时会把字节流对应的编码发送给接收方,这种情况可以理解为发送和接收双方的约定。HTTP协议就有这样的约定,浏览器就是通过约定来识别网页的编码。HTTP协议的响应头会有这样的约定:

  Content-Type: text/html;charset=utf-8

如果打开一个本地的Html文件,其中也会有关于字符编码的约定:

  <meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8“/>

邮件客户端程序也是通过上述约定来识别字符的,在邮件的头部有Charset的声明。

UCS-2/UTF-16BOM头也可以理解为是字符编码的约定,打开文本文件时可以用BOM来识别编码。

靠约定识别编码的情形很多,例如MySQL环境中有一组变量来约定客户端SQL语句的编码以及服务器返回内容的编码。可以用SQL命令来查看这组变量:

  show variables like ‘%character_set%’;

如果没有约定就要尝试去猜测字符编码,以下会介绍几种猜测的方法。

 

通过编码规律识别

UTF-8编码是UCS-2/UCS-4编码按照一定规律转换得到的,UTF-8编码本身有也具有一定规律,这种规律可以作为识别字符编码的依据。下面给出识别一个字符串是否是UTF-8编码的PHP实现:

  <?php

  function isValidUtf8($string)

  {

  $str_len = strlen($string);

  for($i=0;$i<$str_len;)

  {

  $str = ord($string[$i]);

  if($str>=0 && $str < 0×7f)

  {

  $i++;

  continue;

  }

  if($str< 0xc0 || $str>0xfd) return false;

  $count = $str>0xfc?5:$str>0xf8?4:$str>0xf0?3:$str>0xe0?2:1;

  if($i+$count > $str_len) return false;

  $i++;

  for($m=0;$m<$count;$m++)

  {

  if(ord($string[$i])<0×80 || ord($string[$i])>0xbf) return false;

  $i++;

  }

  }

  return true;

  }

  ?>

用此规律识别UTF-8编码会有一定误差,其他编码也会有某些字符符合UTF-8编码规律的情况。

例如GBK编码的“联通”、“学习”等词就符合UTF-8编码的规律。在Windows记事本中只写入“联通”两字后直接保存,重新打开时就会看见两个黑框。原因是记事本错误地把GBK编码的“联通”两字识别为UTF-8编码了,系统字体中没有这两个识别出来的字符,所以只能看见黑框。误把其他编码当作UTF-8编码的例子很多,例如访问URL

http://www.google.cn/search?q=%D1%A7%CF%B0

也会看到错误结果。“%D1%A7%CF%B0”GBK编码的“学习”,Google把它当作了UTF-8编码。

供识别的字符串越长,出现这种识别错误的概率就越低。

 

通过编码范围识别

很多字符编码不像UTF-8编码存在明显规律,例如Big5GBKGB2312等。识别这些编码可以使用的方法是通过编码范围来识别。例如GB2312的编码范围是0xA1A1-0×7E7E,如果某个字符串中有字节不在此范围内,就可以认为该字符串不是GB2312编码。

通过编码范围识别的方法误差很大,原因是很多双字节编码的编码范围重合度很高,一个字符串同时落在几个编码的编码范围就很难确定。ISO-8859-1编码占用了0×00-0xff内所有空间,所以无法通过编码范围来识别。

 

基于语义的识别

基于语义识别字符编码的方法的本质是把文本流当作什么编码来理解更符合语义,具体可以根据字频、词频、上下文环境等方式识别。例如某段文本中“B5C4(’的’字的GBK编码)”两个字节出现的频度比较高,则该段文本是GBK编码的可能性就非常大。基于语义的识别准确度取决于供识别的文本流长度和所采用的识别语料。

 

字符集的识别

字符集编码的识别实际上有两部分,字符编码识别和字符集识别。多数情况下是识别编码,对于通用字符集(UCS)的编码(如UCS-2UTF-8)有时需要识别字符集。例如在只希望处理中文内容的环境中,对拿到的UTF-8编码的文件就需要识别字符集,如果该文件中所有的字符都是韩文字符,就应该被抛弃。

可用的字符集识别方法很多:

通过编码转换来识别。如果把某段文本从UTF-8编码转换到GBK编码时有很多字符不能被转换,就可以认为该文件不是GBK字符集。通常编码转换程序会把不能转换的字符显示为’?'

通过字符编码的范围来判断。CJK汉字在Unicode字符集中占有连续的位置,如果某个UTF-8文件中所有字符都在Unicode定义的CJK汉字区,可以认为该文件是UTF-8编码的中文文件。GBK编码包括俄文字符、日文字符等,这些字符在GBK编码中范围也是连续的。即使某个文件能从UTF-8编码正确转换到GBK编码,也有可能是UTF-8编码的俄文文件。这种情况也可以通过转换后编码的范围来判断。

分享到:
评论

相关推荐

    matlab算法源码文字图像识别

    在本例中,特别强调了是“文字图像识别”,因此可能涉及到光学字符识别(OCR)技术,该技术可以将图像文件中的文字转换成机器编码的文字,以便于进一步的计算机处理。 3. 源码分享方式:描述中提到“提取方式是百度...

    py源码实例自动办公快速提取一串字符中的中文

    因此,我们可以通过判断每个字符的Unicode编码来识别它是否为中文字符。通常情况下,中文字符的Unicode编码范围大致位于`\u4e00`至`\u9fa5`之间。通过遍历字符串中的每一个字符,并检查其是否位于该范围内,即可实现...

    unicode.rar

    在处理中文短信时,使用Unicode编码可以确保短信中的汉字能够被正确识别和传输,避免了由于字符集不兼容导致的乱码问题。 2. **4G模块**: 4G模块是一种嵌入式硬件设备,它集成了4G通信技术,可以连接到4G移动网络...

    C常用算法程序集非数值计算汉字操作

    C语言中处理汉字主要涉及到字符集的选择以及相应的函数调用。 #### 字符集选择 - **GB2312**:早期的中文编码标准,适用于简体中文。 - **GBK**:扩展了GB2312,支持更多的汉字。 - **UTF-8**:国际通用的多字节...

    8051Proteus仿真c源码160128LCD中文显示温度与时间

    - **字符集**:需要准备包含中文字符的字符集,并将其编码为LCD能够识别的格式。 - **程序实现**:编写程序将中文字符转换为相应的代码,并发送给LCD显示屏。 #### 三、实现细节 1. **初始化LCD显示屏**:首先需要...

    数学建模数据集中国2010年人口普查分乡,镇,街道资料(光盘)

    最后,由于您给出的文件信息中包含了一个无法识别的字符串(部分内容),所以这部分无法作为知识内容来解读。如果这个字符串是某种特殊编码或者需要进行解析,请提供更具体的上下文或详细说明。

    配置好的傻瓜化小狼毫全拼+多种双拼+五笔86-98+笔画输入法v200312 - 17种方案

    有些不方便编码的符号集,可使用它的俗称名称的五笔编码,比如文档中要用的编号,就按照“编号”输入,可打出“①②③④⑤⑥⑦⑧⑨⑩??????????”等符号集。 拼音用户也可参照此种编码模式,按照最小优先的原则,以...

    数学建模数据集世界各国教育数据(状况,支出等)(上下)

    由于链接包含不可识别的字符,因此无法直接访问或使用。这需要纠正错误,重新提供一个有效的链接地址。 在使用这样的数据集进行数学建模时,需要考虑到数据的时效性、准确性和代表性,以及是否满足研究问题的需求。...

    算法参考资料20151115北京赛区

    尽管链接包含了不可识别的字符(可能由于编码错误或者其他原因),但从中可以理解到,为了获取算法资料,用户需要通过特定的链接来访问百度网盘中的文件。而链接结尾的“sycy Doyle igolaclub”可能指明了分享文件的...

    使用 PHPMAILER 发送邮件实例应用

    此外,还可以设置发件人的邮箱地址和名称、字符集、编码等: ```php $mail-&gt;From = "send@send.com"; $mail-&gt;FromName = "send"; $mail-&gt;CharSet = "GB2312"; $mail-&gt;Encoding = "base64"; ``` 指定邮件类型为HTML...

Global site tag (gtag.js) - Google Analytics