转:http://www.utf.com.cn/article/s1383
这些相关的东西并不复杂, 但非常容易混淆不清, 尤其是最近看了一些这方面的文章, 即使是被认为是权威的出处, 也经常出现冲突矛盾, 和用词不准确, 解释的概念不清楚的情况:
1. 字符集和编码方案混为一谈. http://www.utf.com.cn/article/s320 中说:
UTF_8字符集
UTF-8是UNICODE的一种变长字符编码后一句话对, 但前一句话, UTF-8是对Unicode字符集的可能的编码方案中的一种, 它本身不是字符集.
2. 字符集只是字义了一个虚拟的, 与电脑无关的一个字符的集合, 规定了在这些集合里面就有哪些字符, 每个字符被赋予一个编号, 编号不是编码, 编号是Unicode术语中的code point的概念, 这些字符就外在的人眼所能看到的形状而言不必是唯一的.
3. Unicode给每个字符赋予的唯一的code point, 只是一个数学概念上的数字, 不要与计算机里对数值的某种表示法联系起来, 还没到那一步, 那是由编码方案决定的. 这个概念上的数, 在Joel on software里的那篇文章"
The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)"章中作者称它是"柏拉图"式的.
4. utf-8究竟最长是4字节还是6字节
The original specification allowed for sequences of up to six bytes covering numbers up to 31 bits (the original limit of the universal character set). However, UTF-8 was restricted by RFC 3629 to use only the area covered by the formal Unicode definition, U+0000 to U+10FFFF, in November 2003.
曾经是6字节, 现在是4字节, 两者都对, 但如果你看到介绍UTF-8的文章说是6字节, 基本可以判断这是比较早的文章. 这跟IPV6的情形不同, IPV6是最初4字节, 最终扩展得更长了, 16字节.
5. 判断ANSI/Unicode 文本的方法
http://www.cppblog.com/liangbo/archive/2006/04/23/6103.html :
如何判断一个文本文件是ANSI还是Unicode? 判断如果文本文件的开头两个字节是0xFF和0xFE,那幺就是Unicode,否则是ANSI |
这样的说法你不忍心说它错, 但是, 也绝不能说它对, 非常容易误导人, 开头两个字节来表示的BOM只是一种约定, 你没有任何办法保证文件的后续内容到底是什么, 也许它既不是ASCII也不是Unicode, 它不能是GB2312编码的? 不能是二进制文件? BOM只是一种约定, 约定只有在两方都严格遵守时才有意义, 你当然可以利用这种约定进行欺骗. 而且. 这个说法还忽略了BOM对于UTF-16有little-endian和big-endian的区分, 这里只给一种情况. 其它的情况都落入了它的"否则". 对UTF-8没有大头小头的问题, 但也有一个三字节的特殊标记约定它是UTF-8编码, UTF-8编码当然也是Unicode编码的一种.
对这一问题真正的答案可能会让人失望: 没办法判断, 但是, 这是理论上的说法, 实际上没有那么无聊的人故意使坏, 做出非此非彼的文件来. 想象一下, HTTP头部没有送给IE Content-Type, 同时HTML代码中也没有<meta http-equiv="Content-Type" charset="text/html; utf-8" />时, IE怎么办? 它怎么知道你的网页编码是什么? 通过猜! 根据内容猜测, 所以有时候它会猜错, 所以你会需要选择不同的编码方案重新显示来避免乱码.
6. unicode就是UCS2, 就是16位的?
unicode是字符集, 跟具体的几位表示没有关系. 当然Unicode标准也规定了字符集的编码方案, 可以认为UTF-8等等都是Unicode标准的平分.
http://www.cppblog.com/liangbo/archive/2006/04/23/6103.html
14. Unicode和DBCS之间的区别 Unicode使用(特别在C程序设计语言环境里)“宽字符集”。「Unicode中的每个字符都是16位宽而不是8位宽。」在Unicode中,没有单单使用8位数值的意义存在。 |
7. UTF-16 是16位的定长编码方案?
Nooooooooooooo!
http://www.answers.com/topic/utf-8-1
UTF-16 is often mistaken to be constant-length, leading to code that works for most text but suddenly fails for non-BMP characters |
BMP中定义的字符可以被16位, 也就是仅仅一个字(WORD, 2字节)的UTF-16所编码.
Plane 0 (0000–FFFF): Basic Multilingual Plane (BMP)
所以, Windows API, WCHAR/w_char(w_char从语言的角度可以是4字节的), Java/C#中的char, 只支持BMP.
尽管UTF-16是变长编码, 它却不象UTF-8一样, 可以是1, 2, 3, 4字节, 它只能是2或4字节.
8. Unicode 能包含多少字符, 它就是双字节的吗?
Unicode was originally a “double-byte,” or 16-digit, binary number (see numeration) code that could represent up to 65,536 items. No longer limited to 16 bits, it can now represent about one million code positions using three encoding forms called Unicode Transformation Formats (UTF)
Unicode reserves 1,114,112 (= 220 + 216or 17 × 216, hexadecimal 110000) code points.
As of Unicode 5.0.0, 101,063 (9.1%) of these codepoints are assigned, with another 137,468 (12.3%) reserved for private use, leaving 875,441 (78.6%) unassignedUCS-2 — a 16-bit, fixed-width encoding that only supports the BMP, considered obsolete
BMP 是按使用频度分配的, 所以UCS-2/或微软的有限的Unicode支持在现实中可能已经是足够了
9. Windows 的内置Unicode到底是怎么回事?
UTF-16 is the standard format for the Windows API (though surrogate support is not enabled by default), 正因为surrogate support不支持, 所以windows API不能支持所有的Unicode字符.
UTF-16 is the native internal representation of text in the Microsoft Windows NT/2000/XP/CE, Qualcomm BREW operating systems; the Java and .NET bytecode environments; Mac OS X's Cocoa and Core Foundation frameworks; and the Qt cross-platform graphical widget toolkit.
UTF-16 作为程序的内部表示是最游行的, 正如UTF-8作为传输和存储是最流行的一样. 因为UTF-16带来了程序处理效率上的优势.
Older Windows NT systems (prior to Windows 2000) only support UCS-2
这就是说XP 能支持UTF-16? 那么它的.NET和WCHAR又怎么办? 定义_UCS4 的宏?
10. GB18030
GB18030 is another encoding form for Unicode, from the Standardization Administration of China. It is the official character set of the People's Republic of China (PRC)
11. 从概念上UCS(Universal Character Set)既然是一个字符集, 区别于编码方案, 为何又要带有-2, -4呢?
UCS是指字符集, 但UCS-2就是指编码方案了.
-2和-4的确是表示字节(8位组), 但UCS-2 是在说一个编码方案, 是编码UCS的早期的一个版本, 早于UTF-16的出现, 我理解-2是说从理论上它可以被2个字节来表示. 而实际的编码方案, 如UTF-8来编码UCS-2字符集时, 由于UCS-2字符集容纳了所有的BMP, 因此可能UTF-8编码UCS-2需要3个字节. 但不会是4个字节.
这里面的确有一些混乱, 字符集后面跟的数字表示字节, 而编码方案后面跟的表示位数, 如UTF-16, 这个位数是一个字符被编码时使用的最少的位数, 而不是一个字符被编码后最终要占用的位数.
12. 大头小头
FE FF (in hexadecimal) for big-endian architectures, or FF FE for little-endian
Technically, with the UTF-16 scheme the BOM prefix is optional, but omitting it is not recommended as UTF-16LE or UTF-16BE should be used instead. If the BOM is missing, barring any indication of byte order from higher-level protocols, big endian is to be used or assumed. The BOM is not optional in the UCS-2 scheme.
技术上说, UTF-16编码中BOM是可选的, 但不推荐忽略, 而应该明确指定UTF-16LE还是UTF-16BE. 如果没指定BOM, 又没有其它的方式指定大头小头, 默认使用大头.
对UCS-2来说BOM不是可选的.
来源:https://www.cnblogs.com/Dragon-China/archive/2007/04/20/720547.html