zoukankan      html  css  js  c++  java
  • 识别不带BOM(无签名)的UTF8文件

    带有签名的UTF-8文件可以通过读取BOM轻松识别, 而不带签名的UFT-8文件只有通过UTF-8编码的规则来尝试辨别。

    先来看看UTF-8编码是如何实现UNICODE字符的:

    UNICODE UTF-8
    00000000 - 0000007F 0xxxxxxx
    00000080 - 000007FF 110xxxxx 10xxxxxx
    00000800 - 0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
    00010000 - 001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    00200000 - 03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    04000000 - 7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

    从上表可以看出如果以个UTF-8字符是以2个或2个以上的字节组成, 则首字节前有多个连续的值为1的比特位, 随后是一个值为0的比特位。

    根据这一特点我们可以尝试识别判断一个文件是否为UFT-8格式。

    代码如下: 

    //data为从文件读取的字节数组

    public bool IsUTF8Bytes(byte[] data)
            {

              
                int charByteCounter = 1;  //计算当前正分析的字符应还有的字节数
               
                byte curByte; //当前分析的字节.


             
                for (int i = 0; i < data.Length; i++)
                {
                    curByte = data[i];

                   

                    if (charByteCounter == 1)
                    {

                        if (curByte >= 0x80)
                        {
                            //判断当前
                            while (((curByte <<= 1) & 0x80) != 0)
                            {

                                charByteCounter++;
                            }

                            //标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X 
                            if (charByteCounter == 1 ||  charByteCounter > 6)
                            {
                                return false;
                            }

                        }
                    }
                    else
                    {
                        //若是UTF-8 此时第一位必须为1
                        if ((curByte & 0xC0) != 0x80)
                        {
                            return false;
                        }
                        charByteCounter--;
                    }
                }


                if (charByteCounter > 1)
                {
                    throw new Exception("非预期的byte格式");
                }
             


                return true;
            }

    需要注意的是,一些比较特殊的字符用此方法无法正确识别是否为UTF8格式,  传说中的微软屏蔽联通就是此问题

    希望此文对大家有帮助

    附:

    1.UTF-8的相关基础知识可以前往这里http://www.codeguru.com/Cpp/misc/misc/multi-lingualsupport/article.php/c10451/

  • 相关阅读:
    当算法提升到哲学层面—小议验证码识别
    2014总结
    [脚本无敌2]python获取cocos 2dx项目文件列表
    单幅图构建三维图
    [思考]画个圈圈诅咒你
    Mybatis2
    Mybatis1
    淘淘商城虚拟机启动命令
    Zookeeper集群搭建zookeeper01启动不成功解决方案
    Mybatis的xml文件的相关配置
  • 原文地址:https://www.cnblogs.com/mingxing/p/1424984.html
Copyright © 2011-2022 走看看