Unicode的基础是什么?为什么需要UTF-8或UTF-16? 我在谷歌上研究过这个,也在这里搜索过,但我不清楚。
在VSS中,当进行文件比较时,有时会有一个消息说两个文件有不同的UTF。为什么会这样呢?
请简单解释一下。
Unicode的基础是什么?为什么需要UTF-8或UTF-16? 我在谷歌上研究过这个,也在这里搜索过,但我不清楚。
在VSS中,当进行文件比较时,有时会有一个消息说两个文件有不同的UTF。为什么会这样呢?
请简单解释一下。
当前回答
最初,Unicode打算使用固定宽度的16位编码(UCS-2)。Unicode的早期采用者,如Java和Windows NT,围绕16位字符串构建了它们的库。
后来,Unicode的范围扩大到包括历史字符,这将需要超过16位编码所支持的65,536个编码点。为了允许在使用UCS-2的平台上表示额外的字符,引入了UTF-16编码。它使用“代理对”来表示补充平面中的字符。
与此同时,许多旧的软件和网络协议使用8位字符串。UTF-8是为了让这些系统可以支持Unicode而不必使用宽字符。它向后兼容7位ASCII。
其他回答
最初,Unicode打算使用固定宽度的16位编码(UCS-2)。Unicode的早期采用者,如Java和Windows NT,围绕16位字符串构建了它们的库。
后来,Unicode的范围扩大到包括历史字符,这将需要超过16位编码所支持的65,536个编码点。为了允许在使用UCS-2的平台上表示额外的字符,引入了UTF-16编码。它使用“代理对”来表示补充平面中的字符。
与此同时,许多旧的软件和网络协议使用8位字符串。UTF-8是为了让这些系统可以支持Unicode而不必使用宽字符。它向后兼容7位ASCII。
Unicode是一种将所有语言中的字符映射到称为码位的特定数值的标准。它这样做的原因是它允许使用相同的代码点集进行不同的编码。
UTF-8和UTF-16就是两种这样的编码。它们将代码点作为输入,并使用一些定义良好的公式对它们进行编码,以生成编码后的字符串。
选择特定的编码取决于您的需求。不同的编码有不同的内存要求,根据将要处理的字符,应该选择使用最少字节序列来编码这些字符的编码。
有关Unicode, UTF-8和UTF-16的更多详细信息,您可以查看这篇文章,
关于Unicode,每个程序员都应该知道的
为什么Unicode ?因为ASCII只有127个字符。128到255在不同的国家是不同的,这就是为什么会有代码页。所以他们说:让我们有1114111个字符。
那么如何存储最高码位呢?您需要使用21位存储它,因此您将使用一个32位的DWORD,浪费了11位。因此,如果使用DWORD存储Unicode字符,这是最简单的方法,因为DWORD中的值与代码点完全匹配。
但是DWORD数组当然比WORD数组大,当然比BYTE数组大。这就是为什么不仅有UTF-32,还有UTF-16。但是UTF-16表示WORD流,而WORD有16位,那么最高码位1114111如何适合WORD呢?它不能!
所以他们把大于65535的所有数都放到DWORD中,他们称之为代理对。这样的代理对是两个单词,可以通过查看前6位来检测。
那么UTF-8呢?它是一个字节数组或字节流,但是最高码位1114111如何适合一个字节?它不能!好的,所以他们也加入了一个DWORD ?或者可能是一个单词,对吧?几乎对吧!
他们发明了utf-8序列,这意味着每个高于127的码位必须被编码成2字节、3字节或4字节序列。哇!但是我们如何检测这样的序列呢?127以内的所有字符都是ASCII,都是一个字节。以110开头的是一个两字节序列,以1110开头的是一个三字节序列,以11110开头的是一个四字节序列。这些所谓的“开始字节”的剩余位属于代码点。
现在,根据序列的不同,后面的字节必须跟着。后面的字节以10开头,其余位为有效负载位的6位,属于码位。将开始字节的有效负载位和后面的字节/秒连接起来,就得到了代码点。这就是UTF-8的魔力所在。
为什么我们需要统一码?
在(不是太)早期,所有存在的都是ASCII。这是可以的,因为所需要的只是一些控制字符、标点符号、数字和字母,就像这句话中的这些。不幸的是,今天这个全球相互交流和社交媒体的陌生世界并没有被预见到,在同一份文件中看到英文、العربية、汉语、ְִרִי、ελληνικ和ភាសាខ្មែរ也不是太罕见(希望我没有弄坏任何旧浏览器)。
但是为了讨论,让我们假设Joe Average是一个软件开发人员。他坚持说他永远只需要英语,因此他只想使用ASCII码。这对用户Joe来说可能没问题,但对软件开发人员Joe来说就不好了。世界上大约有一半的人使用非拉丁字符,使用ASCII可能是对这些人的不体贴,最重要的是,他正在将他的软件向一个庞大的、不断增长的经济体关闭。
Therefore, an encompassing character set including all languages is needed. Thus came Unicode. It assigns every character a unique number called a code point. One advantage of Unicode over other possible sets is that the first 256 code points are identical to ISO-8859-1, and hence also ASCII. In addition, the vast majority of commonly used characters are representable by only two bytes, in a region called the Basic Multilingual Plane (BMP). Now a character encoding is needed to access this character set, and as the question asks, I will concentrate on UTF-8 and UTF-16.
内存方面的考虑
那么有多少字节可以访问这些编码中的哪些字符呢?
utf - 8:
1字节:标准ASCII码 2字节:阿拉伯语,希伯来语,大多数欧洲脚本(最明显的不包括格鲁吉亚) 3字节:BMP 4字节:所有Unicode字符
utf - 16:
2字节:BMP 4字节:所有Unicode字符
值得一提的是,不在BMP中的字符包括古代文字、数学符号、音乐符号和更罕见的中文、日语和韩语(CJK)字符。
如果您将主要使用ASCII字符,那么UTF-8肯定更节省内存。但是,如果您主要使用非欧洲脚本,使用UTF-8的内存效率可能比UTF-16低1.5倍。在处理大量文本时,如大网页或冗长的word文档,这可能会影响性能。
编码的基本知识
注意:如果您知道UTF-8和UTF-16是如何编码的,请跳到下一节了解实际应用。
UTF-8: For the standard ASCII (0-127) characters, the UTF-8 codes are identical. This makes UTF-8 ideal if backwards compatibility is required with existing ASCII text. Other characters require anywhere from 2-4 bytes. This is done by reserving some bits in each of these bytes to indicate that it is part of a multi-byte character. In particular, the first bit of each byte is 1 to avoid clashing with the ASCII characters. UTF-16: For valid BMP characters, the UTF-16 representation is simply its code point. However, for non-BMP characters UTF-16 introduces surrogate pairs. In this case a combination of two two-byte portions map to a non-BMP character. These two-byte portions come from the BMP numeric range, but are guaranteed by the Unicode standard to be invalid as BMP characters. In addition, since UTF-16 has two bytes as its basic unit, it is affected by endianness. To compensate, a reserved byte order mark can be placed at the beginning of a data stream which indicates endianness. Thus, if you are reading UTF-16 input, and no endianness is specified, you must check for this.
可以看到,UTF-8和UTF-16彼此完全不兼容。所以如果你在做I/O,确保你知道你在使用哪种编码!有关这些编码的进一步细节,请参阅UTF常见问题解答。
实际编程注意事项
Character and string data types: How are they encoded in the programming language? If they are raw bytes, the minute you try to output non-ASCII characters, you may run into a few problems. Also, even if the character type is based on a UTF, that doesn't mean the strings are proper UTF. They may allow byte sequences that are illegal. Generally, you'll have to use a library that supports UTF, such as ICU for C, C++ and Java. In any case, if you want to input/output something other than the default encoding, you will have to convert it first.
Recommended, default, and dominant encodings: When given a choice of which UTF to use, it is usually best to follow recommended standards for the environment you are working in. For example, UTF-8 is dominant on the web, and since HTML5, it has been the recommended encoding. Conversely, both .NET and Java environments are founded on a UTF-16 character type. Confusingly (and incorrectly), references are often made to the "Unicode encoding", which usually refers to the dominant UTF encoding in a given environment.
库支持:您正在使用的库支持某种编码。哪一个?他们支持极端情况吗?因为需要是发明之母,UTF-8库通常会正确地支持4字节字符,因为1、2甚至3字节字符经常出现。然而,并不是所有的UTF-16库都正确地支持代理对,因为它们很少出现。
字符计数:Unicode中存在组合字符。例如,代码点U+006E (n)和U+0303(一个组合波浪号)组成ñ,而代码点U+00F1组成ñ。它们看起来应该是相同的,但是一个简单的计数算法将为第一个示例返回2,为后一个示例返回1。这并不一定是错误的,但也可能不是理想的结果。
平等比较:A、А和Α看起来一样,但它们分别是拉丁语、西里尔语和希腊语。你也有C和Ⅽ这样的情况。一个是字母,另一个是罗马数字。此外,我们还需要考虑组合字符。有关更多信息,请参见Unicode中的重复字符。
代理对:这些在Stack Overflow中经常出现,所以我只提供一些示例链接:
获取字符串长度 删除代理对 回文检查
UTF代表Unicode转换格式。基本上,在当今世界,有数百种其他语言编写的脚本,这些脚本的格式不包括在以前使用的基本ASCII中。因此,UTF应运而生。
UTF-8具有字符编码功能,其代码单位为8位,而UTF-16为16位。