识别不带BOM(无签名)的UTF-8文件

带有签名的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/

时间: 2024-08-29 04:24:43

识别不带BOM(无签名)的UTF-8文件的相关文章

编码-如何使用visual studio 2013保存php文件默认就是utf-8无签名的?

问题描述 如何使用visual studio 2013保存php文件默认就是utf-8无签名的? 使用visual studio 2013开发php时,经常文件的编码会变成utf-8带签名的,这样运行时页面样式会出问题,百度后发现这是微软格式文件的问题,请教大家,能否修改配置,使得每次默认修改就是utf-8无签名编码,具体如下图:谢谢大家: 解决方案 在工具-选项-文本编辑器-自动检测没有签名的utf-8文件(我不用中文版的vs,可能文字有出入),你找下. 解决方案二: Using UTF-8

Java处理带BOM的文本

说起BOM,这个问题还比较麻烦,因为BOM不可见,但用程序做不同编码文本处理时候却常常需要考虑 到BOM的问题.在此之前,先对BOM做个简单认识. 先看看带BOM的文件: 源文件: 16进制打开:

请求-VS2010自带数据库无。。。。。。。。。。。。。。。。。。。

问题描述 VS2010自带数据库无................... 大神,请求指点:VS2010自带数据库连接不上????怎么办.?? 解决方案 你是如何操作的呢?为能连接,具体的现象又是什么呢? 解决方案二: 要自己装一个数据库的,例如sql server 2008之类的,再连接 解决方案三: 数据库都是自己安装再用VS连接的 解决方案四: 用的什么方式连接的?确定已经成功安装数据库了? 解决方案五: VS提供的数据库连接,填入服务器名.端口.用户名.密码后,左下方会有一个**测试连接*

带高级搜索、书签功能、文件菜单等功能的Hibernate 3.2 Spring 2.0的chm格式Reference

http://yulimin.javaeye.com/blog/46928 我制作出了带高级搜索.书签功能.文件菜单等更多功能的.chm格式的文档了,需要的请下载最新版本的. 同时把原来的Spring 2.0的文档也重新制作了一下.:) Hibernate Reference 3.2 :http://www.javaeye.com/topics/download/072de89c-9b5c-4958-b274-c1beb0753e9b Spring Reference 2.0:http://ww

安卓系统自带的播放器,支持流媒体文件播放吗?

问题描述 安卓系统自带的播放器,支持流媒体文件播放吗? 如题.从网络上获取的流媒体文件,能不能使用安卓自带的视频播放器播放? 解决方案 安卓系统自带的播放器是可以播放在线流媒体视频的,自带的播放器支持标准流媒体视频播放但是良好的网速也是必须的,否则播放网络视频时可能会不流畅

android签名.jks和.keystore文件有什么区别?

问题描述 android签名.jks和.keystore文件有什么区别? 用AS签名时的新建方式新建了.jks文件 就可以成功签名, 但是用别人的keystore文件重新签名就不行Error:Execution failed for task ':app:packageDebug'. Failed to read key from keystore 指定路径了, 密码也对了, 就是每次都是这个错.

浏览器自带抓包工具怎么查看流文件

问题描述 浏览器自带抓包工具怎么查看流文件,求大神指教,,, 解决方案 解决方案二:流文件?就是图片了?这个在F12里面是以Base64文件格式传递的

Ubuntu无授权访问共享只读公共文件夹

Ubuntu无授权访问共享只读公共文件夹操作如下: sudo mkdir /home/publicsudo chmod 777 /home/public/sudo cp /etc/samba/smb.conf /etc/samba/smb.conf_backupsudo gedit /etc/samba/smb.conf 搜寻这一行文字 ...; security = user... 用下面这一行取代 security = share 将下列几行新增到文件的最后面 [public]comment

一个带采集远程文章内容,保存图片,生成文件等完整的采集功能

本文提供了一套完整的ASP采集功能函数,包含提取地址的原字符,保存远程的文件到本地模拟登录,获取网页源码等功能函数,阿里西西站长推荐收藏! '================================================== '函数名:GetHttpPage '作  用:获取网页源码 '参  数:HttpUrl ------网页地址 '================================================== Function GetHttpPage(