首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

检拆字节流是否是UTF8编码

2012-11-09 
检测字节流是否是UTF8编码几天前偶尔看到有人发帖子问“如何自动识别判断url中的中文参数是GB2312还是Utf-8

检测字节流是否是UTF8编码

几天前偶尔看到有人发帖子问“如何自动识别判断url中的中文参数是GB2312还是Utf-8编码”
也拜读了wcwtitxu使用巨牛的正则表达式检测UTF8编码的算法。
使用无数或条件的正则表达式用起来却是性能不高。
刚好曾经在项目中有类似的需求,这里把处理思路和整理后的源代码贴出来供大家参考
先聊聊原理:
UTF8的编码规则如下表
UTF8 Encoding Rule
看起来很复杂,总结起来如下:
ASCII码(U+0000 - U+007F),不编码
其余编码规则为
??? ?第一个Byte二进制以形式为n个1紧跟个0 (n >= 2), 0后面的位数用来存储真正的字符编码,n的个数说明了这个多Byte字节组字节数(包括第一个Byte)
??? ?结下来会有n个以10开头的Byte,后6个bit存储真正的字符编码。
??? 因此对整个编码byte流进行分析可以得出是否是UTF8编码的判断。
根据这个规则,我给出的C#代码如下:

/// <summary>///This is a test class for EncodingHelperTest and is intended///to contain all EncodingHelperTest Unit Tests///</summary>[TestClass()]public class EncodingHelperTest{    /// <summary>    ///  Normal test for this method.    ///</summary>    [TestMethod()]    public void IsTextUTF8Test()    {        for (int i = 0; i < 1000; i++)        {            List<Char> chars = new List<char>();            chars.Add('中');             List<UnicodeCategory> temp = new List<UnicodeCategory>();            Random rd = new Random((int)(DateTime.Now.Ticks & 0x7FFFFFFF));             for (int j = 0; j < 255; j++)            {                char ch = (char)rd.Next(0xFFFF);                UnicodeCategory uc = System.Globalization.CharUnicodeInfo.GetUnicodeCategory(ch);                if (uc == UnicodeCategory.Surrogate || // Single surrogate could not be encoding correctly.                    uc == UnicodeCategory.PrivateUse || // Private use blocks should be excluded.                    uc == UnicodeCategory.OtherNotAssigned                    )                {                    j--;                }                else                {                    chars.Add(ch);                    temp.Add(uc);                }            }             string str = new string(chars.ToArray());             byte[] inputStream = Encoding.UTF8.GetBytes(str);            bool expected = true;            bool actual;            actual = EncodingHelper.IsTextUTF8(ref inputStream);            Assert.AreEqual(expected, actual, string.Format("UTF8_Assert Fails at:{0}", str));             inputStream = Encoding.GetEncoding(932).GetBytes(str);            expected = false;             actual = EncodingHelper.IsTextUTF8(ref inputStream);            Assert.AreEqual(expected, actual, string.Format("ShiftJIS_Assert Fails at:{0}", str));        }    }     /// <summary>    ///   Check with All ASCII chars    /// </summary>    [TestMethod]    public void IsTextUTF8Test_AllASCII()    {        string str = "ABCDEFGHKLHSJKLDFHJKLHAJKLSHJKLHAJKLSHDJKLAHSDJKLHAJKLSDHJKLASHDJKLHASJKLDHJKLASD";         byte[] inputStream = Encoding.UTF8.GetBytes(str);        bool expected = false;        bool actual;        actual = EncodingHelper.IsTextUTF8(ref inputStream);        Assert.AreEqual(expected, actual, string.Format("UTF8_Assert Fails at:{0}", str));      }}

?另:
如果是判断一个文件是否使用了UTF8编码,不一定非用这种方法,因为通常以UTF8格式保存的文件最初两个字符是BOM头,标示该文件使用了UTF8编码。
参考:
维基百科:http://en.wikipedia.org/wiki/UTF-8

?

其实java的操作也类似,有时间再写个

热点排行