几天前偶尔看到有人发帖子问“如何自动识别判断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>
/// Determines whether the given <paramref name="inputStream"/>is UTF8 encoding bytes.
/// </summary>
/// <param name="inputStream">
/// The input stream.
/// </param>
/// <returns>
/// <see langword="true"/> if given bystes stream is in UTF8 encoding; otherwise, <see langword="false"/>.
/// </returns>
/// <remarks>
/// All ASCII chars will regards not UTF8 encoding.
/// </remarks>
public static bool IsTextUTF8(ref byte[] inputStream)
{
int encodingBytesCount = 0;
bool allTextsAreASCIIChars = true;
for (int i = 0; i < inputStream.Length; i++)
{
byte current = inputStream[i];
if ((current & 0x80) == 0x80)
{
allTextsAreASCIIChars = false;
}
// First byte
if (encodingBytesCount == 0)
{
if ((current & 0x80) == 0)
{
// ASCII chars, from 0x00-0x7F
continue;
}
if ((current & 0xC0) == 0xC0)
{
encodingBytesCount = 1;
current <<= 2;
// More than two bytes used to encoding a unicode char.
// Calculate the real length.
while ((current & 0x80) == 0x80)
{
current <<= 1;
encodingBytesCount++;
}
}
else
{
// Invalid bits structure for UTF8 encoding rule.
return false;
}
}
else
{
// Following bytes, must start with 10.
if ((current & 0xC0) == 0x80)
{
encodingBytesCount--;
}
else
{
// Invalid bits structure for UTF8 encoding rule.
return false;
}
}
}
if (encodingBytesCount != 0)
{
// Invalid bits structure for UTF8 encoding rule.
// Wrong following bytes count.
return false;
}
// Although UTF8 supports encoding for ASCII chars, we regard as a input stream, whose contents are all ASCII as default encoding.
return !allTextsAreASCIIChars;
}
再附上单元测试代码:
/// <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的操作也类似,有时间再写个
分享到:
相关推荐
在IT领域,字节流(Byte Stream)是数据在计算机内部和网络中传输的基本单位,而编码则关乎数据如何被转换成字节流以便于处理和传输。在处理字节流编码时,我们通常会遇到诸如字符集、字节顺序标记(BOM)、解码与...
例如,如果你已经知道或检测到源文本是GBK编码,你可以使用“转换编码”命令,将GBK编码的文本转换为UTF-8编码。 4. **写入UTF-8文本**:转换后的UTF-8编码文本需要保存到新的文件中,可以使用“写文本文件全部”...
编码转换的原理通常是读取原始编码的字节流,然后根据目标编码的规则重新分配字节。对于GBK到UTF-8的转换,首先需要将GBK编码的每个双字节视为一个独立的字符,然后查找对应的Unicode码点,最后按照UTF-8的规则将其...
例如,我们可以创建一个`CharsetDetector`实例,然后使用它的`detect`方法来检测输入的字节流是否符合UTF8编码规范。如果需要转换,可以使用`CharsetEncoder`的`encode`方法将其他编码的字符转换为UTF8编码的字节...
"批量utf文件转utf8-bom"这个主题指的是将一批以UTF编码的文件转换为带有BOM(Byte Order Mark)的UTF-8编码。BOM是一个特殊的字节序列,用于标识文件的编码类型,对于UTF-8编码,BOM的字节序列为0xEF, 0xBB, 0xBF。...
首先,UTF8是一种广泛使用的变长Unicode字符编码,它能够表示Unicode字符集中的所有字符。UTF8的特点是前几个字节用于识别字符的范围,对于ASCII字符(英文字符和某些符号),UTF8只使用一个字节,这使得UTF8在处理...
BOM,即字节顺序标记,是UTF-8编码中可选的一部分,用于标识数据流的字节顺序。在大多数情况下,BOM在UTF-8编码中并不必要,因为它默认是小端序,但对于某些程序或系统,BOM可能有助于识别文件的编码方式。 在处理...
UTF-8是一种广泛使用的Unicode字符编码方案,它可以表示Unicode标准中的所有字符,且在互联网上被普遍采用。在这个压缩包中,我们有三个文件:UTF8.cpp、yufa100.txt和TestPrj.txt。 UTF8.cpp很可能是一个C++源代码...
UTF-8是一种广泛使用的字符编码标准,尤其在互联网上,几乎所有的网页都采用UTF-8编码。这个"判断文本编码是否为UTF-8格式易语言源码例子"是一个针对初学者的教程,旨在教授如何在易语言中识别和验证文本文件的编码...
例如,Unicode字符集包含了许多字符,而UTF-8是Unicode的一个实现,规定了如何用8位字节来编码这些字符。 7. 实际应用: 在开发跨平台、多语言的应用时,理解UTF-8的细节非常关键。例如,数据库存储、网页设计、...
UTF-8是一种广泛使用的Unicode字符编码方式,它能够表示世界上几乎所有的字符。然而,UTF-8有一个特殊的形式,即带BOM(Byte Order Mark)的UTF-8,这个BOM在某些情况下可能会引发问题。本文将详细探讨Java中如何...
UTF-8是一种多字节的Unicode编码方式,可以表示世界上几乎所有的字符,包括各种语言的字符。它是互联网上最常用的字符编码格式,因为它兼容ASCII,并且在处理多种语言时具有良好的通用性。 转换“pb12 gb转utf-8”...
3. 重新编码:然后,根据目标编码方式,将字符序列重新编码为新的字节流。 4. 写入新文件:最后,将新编码的字节流写入目标文件。 在实际应用中,这个过程可能会涉及到更复杂的处理,比如错误检测和恢复,以及处理...
UTF-8(8位Unicode转换格式)是一种广泛使用的多字节字符编码方案,它兼容ASCII编码并能表示Unicode字符集中的所有字符。UTF-8最大的优点在于其前128个字符与ASCII编码完全一致,因此在英语为主的系统和网络中非常...
GBK是中文环境下广泛使用的编码方式,而UTF-8是一种更为通用的多语言编码格式,支持全球各种字符集。由于历史原因或特定系统需求,开发者可能需要在两者之间进行转换。 这款工具的一大特点在于它能自动检测文件的...
在实际操作中,GBK转UTF-8的过程包括读取GBK编码的文件,对每个字节流进行解码得到对应的字符,然后按照UTF-8的编码规则重新编码成新的字节流,最后将这个字节流写入新的文件。由于GBK和UTF-8编码方式的不同,直接...
2. **读取UTF-8**:在C/C++中,可以使用标准库如`fread`或`scanf`来读取文件内容,但由于它们默认处理的是字节流,因此需要额外的逻辑来识别UTF-8编码的字符边界。 3. **写入UTF-8**:类似地,`fwrite`和`fprintf`...
在网络通信中,数据通常以字节流的形式传输,因此正确解析UTF-8编码的字符至关重要,避免因编码问题导致的信息丢失或误解。 总的来说,UTF-8中文字符表是一个非常实用的工具,它对于跨平台的Web开发和系统间的文本...
- **编码**:用`UTF-8`编码规则将Unicode字符序列重新编码成字节流。 - **写入文件**:将新的字节流写入新的`UTF-8`文件。 5. **工具与编程语言支持** 许多编程语言如Python、Java、JavaScript等都有内置函数...