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/

  • 相关阅读:
    UVALive 5983 MAGRID DP
    2015暑假训练(UVALive 5983
    poj 1426 Find The Multiple (BFS)
    poj 3126 Prime Path (BFS)
    poj 2251 Dungeon Master 3维bfs(水水)
    poj 3278 catch that cow BFS(基础水)
    poj3083 Children of the Candy Corn BFS&&DFS
    BZOJ1878: [SDOI2009]HH的项链 (离线查询+树状数组)
    洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)
    洛谷P3065 [USACO12DEC]第一!First!(Trie树+拓扑排序)
  • 原文地址:https://www.cnblogs.com/mingxing/p/1424984.html
Copyright © 2011-2022 走看看