主页 > Linux教程 > 正文

Unicode,UTF-8和UTF-16的差异与联络

概念

先说一说根本的概念,这包含什么是Unicode,什么是UTF-8,什么是UTF-16。

Unicode,UTF-8,UTF-16完好的阐明请参阅Wiki(Unicode,UTF-8,UTF-16)。用比较简单的话来说便是,Unicode界说了一切可以用来表明字符的数值调集(称之为Code Point)。UTF-8和UTF-16等UTF规范界说了这些数值和字符的映射联系。

UTF-8

优势

UTF-8最大的优势是,没有字节序的概念。所以特别适宜用于字符串的网络数据传输,不必考虑巨细端问题。关于非英文网页(关于咱们而言,简单说东亚文字网页),可以防止各种乱码问题。

下风

本地字符串处理过程中,假如运用UTF-8,关于英文字符的处理没有太大的问题。一个char变量表明一个英文字符。可是关于中文等远东字符集来说,就比较坑爹了。char str[]; str[0]并不能完好表明一个汉字。UTF-8编码格局下,一个汉字需求至少3个char才干表明。这关于经过下标来操作字符串的操作来说是十分苦楚的一件工作。

别的,一个汉字需求至少3个char来表明,也让汉字在网络传输上存在下风,占用太多流量(可是假如启用了紧缩,实际上不同并不大。而且现在许多中文网站都默许将编码从GBK改成了UTF-8)。

UTF-16

优势

UTF-16 LE是windows上默许的Unicode编码办法,运用wchar_t表明。一切wchar_t *类型的字符串(包含硬编码在.h/.cpp里的字符串字面值),VC都主动选用UTF-16的编码(字符串字面值,literal string,存在许多坑。特别是char *类型的字面值,终究内存运用何种编码办法彻底取决于当时文件的编码办法。也便是说当时文件假如是GBK编码的,那么文件里char * str = "正午",str指向的内存字符串二进制是运用GBK编码的。假如文件编码是UTF-8,那么内存是运用UTF-8编码。所以为什么一向要着重字符串应该放在资源文件里,而不是硬编码在.h/.cpp文件里!)。

UTF-16别的一个优势便是常用字符都可以运用两个个字节表明,也便是一个wchar_t(这儿指Windows渠道)。所以,在Windows渠道上,特别适宜运用wchar_t来作为字符串的存储基类型。一个wchar_t表明一个字符。操作运用十分便利。

下风

没有一致的表明UTF-16编码的字符类型。C++98/03里对wchar_t的界说是十分广泛的。这导致在Windows渠道上,wchar_t是2字节的;在Unix-like体系上是4字节的。代码移植上,可能会遇到应战(我没移植过,所以不确定会有什么难度,以及难度有多大)。

即便最新的C++11里现已界说除了char16_t表明UTF-16,MS的VS2013还不支撑char16_t。所以现在运用char16_t还不具移植性。

据我了解,UTF-16编码和GBK编码比较,还存在一个排序的下风。也便是说,假如要依照汉语拼音的字母次序对汉字进行排序,GBK会得到正确的成果,而UTF-16就不可(暂时我还没这种需求,所以我没验证过,不过如同我立刻就要与到这种需求了,到时候我再验证下)。

UTF-16编码字符串的网络传输,要考虑巨细端的问题。别的网络传输中假如一个字节信息丢掉,剩余的字符串都无法正确解析。通通乱码。

别的,UTF-16并不是定长类型。所以仍是存在生僻字运用4个字节编码而不是2个字节(可是Windows有破例。在Windows(NT内核)渠道,从MSDN的各种表述来看,好像一个wchar_t便是一个字符。更多关于Windows渠道字符编码的问题参阅知乎答复和相关谈论)。

UTF-32

优势

这个优势就显着了,一切字符都是4字节,fix-length。一个wchar_t(Unix-like体系上)表明一个字符。

下风

关于以英文为主的字符串来说,空间耗费大。

面对和上面UTF-16相同的问题。一致性,排序,网络传输,数据丢掉后无法康复。char32_t VS2013还不支撑(乃至VS 14 CPT也没计划支撑)。

总结

UTF-8最适宜用来作为字符串网络传输的编码格局。UTF-16最适宜当作本地字符串编码格局。假如界说好了网络传输协议,那么UTF-16也十分适宜当作网络字符串传输的编码格局,特别是中文等远东地区字符集。比起UTF-8来说,节约一点点流量。UTF-32没什么特别嗜好或许需求的话,暂时还用不上。

我个人觉得最佳实践应该是:

Linux上运用char,选用UTF-8编码。

网络传输运用UTF-8编码。

Windows上运用wchar_t / char16_t,选用UTF-16编码。将收到的网络数据一致从UTF-8转码到UTF-16。在Windows上应该铭记没有char / std::string这种类型的字符/字符串,只要wchar_t / char16_t / std::wstring / std::u16string。


上一篇:CentOS下检查体系版别的4种办法
下一篇:linux下3种检测长途端口是否翻开的办法

PythonTab微信大众号:

Python技术交流合作群 ( 请勿加多个群 ):

群1: 87464755

群2: 333646237

群3: 318130924

群4: 385100854