Ant*_*nes 348
UTF-8在ASCII字符代表文本块中的大多数字符的情况下具有优势,因为UTF-8将所有字符编码为8位(如ASCII).还有利的是,仅包含ASCII字符的UTF-8文件具有与ASCII文件相同的编码.
UTF-16在ASCII不占优势的地方更好,因为它主要使用每个字符2个字节.对于高阶字符,UTF-8将开始使用3个或更多字节,对于大多数字符,UTF-16仅保留2个字节.
UTF-32将覆盖4个字节中的所有可能字符.这让它变得非常臃肿.我想不出使用它有什么好处.
Ada*_*eld 308
简而言之:
长:请参阅维基百科:UTF-8,UTF-16和UTF-32.
Qua*_*noi 109
UTF-8可变1到4个字节.
UTF-16是可变的2或4个字节.
UTF-32固定为4个字节.
jal*_*alf 75
Unicode定义了一个巨大的字符集,为每个图形符号分配一个唯一的整数值(这是一个主要的简化,实际上并不是真的,但它足够接近这个问题的目的).UTF-8/16/32只是对此进行编码的不同方式.
简而言之,UTF-32为每个字符使用32位值.这允许他们为每个角色使用固定宽度的代码.
UTF-16默认使用16位,但这只能为您提供65k个可能的字符,这对于完整的Unicode集来说已经足够了.所以一些字符使用16位值对.
UTF-8默认使用8位值,这意味着127个第一个值是固定宽度的单字节字符(最高有效位用于表示这是多字节序列的开始,留下7个实际字符值的位).所有其他字符编码为最多4个字节的序列(如果存储器服务).
这导致了我们的优势.任何ASCII字符都与UTF-8直接兼容,因此对于升级旧版应用程序,UTF-8是一种常见且明显的选择.在几乎所有情况下,它也将使用最少的内存.另一方面,您无法保证角色的宽度.它可能是1,2,3或4个字符宽,这使得字符串操作变得困难.
UTF-32是相反的,它使用最多的内存(每个字符是固定的4字节宽),但另一方面,你知道每个字符都有这个精确的长度,因此字符串操作变得更加简单.您可以根据字符串的字节长度计算字符串中的字符数.你不能用UTF-8做到这一点.
UTF-16是一种妥协.它允许大多数字符符合固定宽度的16位值.因此,只要您没有中文符号,音符或其他符号,就可以假设每个字符都是16位宽.它使用的内存比UTF-32少.但它在某种程度上是"两个世界中最糟糕的".它几乎总是使用比UTF-8更多的内存,它仍然无法避免困扰UTF-8(可变长度字符)的问题.
最后,与平台支持的内容一起使用通常很有帮助.Windows在内部使用UTF-16,因此在Windows上,这是显而易见的选择.
Linux有所不同,但它们通常使用UTF-8来处理符合Unicode的所有内容.
如此简短的回答:所有三种编码都可以编码相同的字符集,但它们将每个字符表示为不同的字节序列.
roo*_*ook 41
Unicode是一个标准,关于UTF-x,您可以将其视为一些实际用途的技术实现:
Mar*_*oun 23
我试着在我的博文中给出一个简单的解释.
需要32位(4字节)来编码任何字符.例如,为了使用此方案表示"A"字符代码点,您需要以32位二进制数写入65:
00000000 00000000 00000000 01000001 (Big Endian)
Run Code Online (Sandbox Code Playgroud)
如果仔细观察一下,你会发现使用ASCII方案时,最右边的7位实际上是相同的位.但由于UTF-32是固定宽度方案,我们必须附加三个额外的字节.这意味着如果我们有两个只包含"A"字符的文件,一个是ASCII编码的,另一个是UTF-32编码的,它们的大小相应地是1个字节和4个字节.
许多人认为,由于UTF-32使用固定宽度32位来表示代码点,因此UTF-16的固定宽度为16位.错误!
在UTF-16中,代码点可以用16位或32位表示.所以这个方案是可变长度编码系统.与UTF-32相比有什么优势?至少对于ASCII,文件的大小不会是原始文件的4倍(但仍然是两倍),因此我们仍然不能向后兼容ASCII.
由于7位足以表示"A"字符,因此我们现在可以使用2个字节而不是像UTF-32那样的4个字节.它看起来像:
00000000 01000001
Run Code Online (Sandbox Code Playgroud)
你猜对了..在UTF-8中,代码点可以用32,16,24或8位表示,而作为UTF-16系统,这个也是可变长度编码系统.
最后,我们可以用与ASCII编码系统相同的方式表示"A":
01001101
Run Code Online (Sandbox Code Playgroud)
考虑中文字母"语" - 其UTF-8编码为:
11101000 10101010 10011110
Run Code Online (Sandbox Code Playgroud)
虽然它的UTF-16编码更短:
10001010 10011110
Run Code Online (Sandbox Code Playgroud)
为了理解表示及其解释方式,请访问原始帖子.
Jef*_*son 19
除非大部分字符来自CJK(中文,日文和韩文)字符空间,否则UTF-8将是最节省空间的.
UTF-32最适合通过字符偏移随机访问字节数组.
var*_*tec 13
在UTF-32中,所有字符都用32位编码.优点是您可以轻松计算字符串的长度.缺点是对于每个ASCII字符,您浪费了额外的三个字节.
在UTF-8字符具有可变长度时,ASCII字符以一个字节(八位)编码,大多数西方特殊字符以两个字节或三个字节编码(例如€是三个字节),并且更多奇特的字符可以占用到四个字节.明显的缺点是,先验你无法计算字符串的长度.但与UTF-32相比,编码拉丁(英语)字母文本所需的字节数要少得多.
UTF-16也是可变长度的.字符以两个字节或四个字节编码.我真的没有看到这一点.它具有可变长度的缺点,但没有像UTF-8那样节省空间的优点.
在这三个中,显然UTF-8是最广泛传播的.
Far*_*mov 13
我做了一些测试来比较MySQL中UTF-8和UTF-16之间的数据库性能.
根据您的开发环境,您甚至可能无法选择内部使用的字符串数据类型的编码.
但是对于存储和交换数据,我总是使用UTF-8,如果你有选择的话.如果您主要拥有ASCII数据,这将为您提供最少量的数据传输,同时仍然可以对所有内容进行编码.优化最少的I/O是现代机器的发展方向.
我很惊讶这个问题已经有 11 年了,而且没有一个答案提到 utf-8 的 #1 优势。
utf-8 通常适用于不支持 utf-8 的程序。这部分是它的设计目的。其他答案提到前 128 个代码点与 ASCII 相同。所有其他代码点都是由 8 位值和高位集(值从 128 到 255)生成的,因此从非 unicode 感知程序的 POV 来看,它只是将字符串视为带有一些额外字符的 ASCII。
例如,假设您编写了一个程序来添加行号,从而有效地执行此操作(为了简单起见,我们假设行尾只是 ASCII 13)
// pseudo code
function readLine
if end of file
return null
read bytes (8bit values) into string until you hit 13 or end or file
return string
function main
lineNo = 1
do {
s = readLine
if (s == null) break;
print lineNo++, s
}
Run Code Online (Sandbox Code Playgroud)
将 utf-8 文件传递给该程序将继续工作。类似地,拆分制表符、逗号、解析 ASCII 引号或其他只有 ASCII 值有意义的解析都只适用于 utf-8,因为 utf-8 中没有出现 ASCII 值,除非它们实际上是那些 ASCII 值
其他一些答案或评论提到 utf-32 的优点是您可以单独处理每个代码点。例如,这建议您可以采用像“ABCDEFGHI”这样的字符串,并在每个第三个代码点处将其拆分为
ABC
DEF
GHI
Run Code Online (Sandbox Code Playgroud)
这是错误的。许多代码点会影响其他代码点。例如,颜色选择器代码点可让您在 ????? 之间进行选择。如果您在任意代码点拆分,则会破坏它们。
另一个例子是双向代码点。以下段落没有倒着输入。它前面只是 0x202E 代码点
- ?此行不向后输入,只向后显示
所以不,utf-32 不会让你随意操作 unicode 字符串而不考虑它们的含义。它将让您无需额外代码即可查看每个代码点。
仅供参考,utf-8 的设计使查看任何单个字节都可以找到当前代码点或下一个代码点的开头。
如果在 utf-8 数据中取任意字节。如果它 < 128,它本身就是正确的代码点。如果 >= 128 和 < 192(前 2 位是 10),那么要找到代码点的开始,您需要查看前一个字节,直到找到一个值 >= 192 的字节(前 2 位是 11 )。在该字节处,您找到了代码点的开头。该字节对有多少后续字节构成代码点进行编码。
如果您想找到下一个代码点,只需扫描直到字节 < 128 或 >= 192 ,这就是下一个代码点的开始。
字节数 | 第一个代码点 | 最后一个代码点 | 字节 1 | 字节 2 | 字节 3 | 字节 4 |
---|---|---|---|---|---|---|
1 | U+0000 |
U+007F |
0xxxxxxx |
|||
2 | U+0080 |
U+07FF |
110xxxxx |
10xxxxxx |
||
3 | U+0800 |
U+FFFF |
1110xxxx |
10xxxxxx |
10xxxxxx |
|
4 | U+10000 |
U+10FFFF |
11110xxx |
10xxxxxx |
10xxxxxx |
10xxxxxx |
xxxxxx
代码点的位在哪里。连接字节中的 xxxx 位以获取代码点
归档时间: |
|
查看次数: |
200773 次 |
最近记录: |