UTF-8编码字符的最大字节数是多少?


79

一个UTF-8编码字符的最大字节数是多少?

我将对以UTF-8编码的String的字节进行加密,因此需要能够计算出UTF-8编码的String的最大字节数。

有人可以确认单个UTF-8编码字符的最大字节数吗?


1
确实看过常见资源,例如Wikipedia的UTF-8文章,首先……对吗?

5
我读了几篇给出了不同答案的文章...实际上,我的印象是答案是3,所以我很高兴问到
Edd 2012年

2
我将在此处留下youtube链接,其中包含汤姆·斯科特(Tom Scott)的字符,符号,Unicode奇迹:goo.gl/sUr1Hf。您将听到并看到一切从ASCII字符编码到utf-8的演变过程。
罗伊·李

有关长度计算代码示例,另请参见在Java字符串的UTF-8中计算长度而不实际对其进行编码
Vadzim,

Answers:


86

根据RFC3629,每个字符的最大字节数为4,该字符将字符表限制为U+10FFFF

在UTF-8中,使用1到4个八位字节的序列对U + 0000..U + 10FFFF范围(UTF-16可访问范围)中的字符进行编码。

(原始规范允许对过去的代码点最多使用六个字节的字符代码U+10FFFF。)

代码小于128的字符仅需要1个字节,接下来的1920个字符代码仅需要2个字节。除非您使用的是深奥的语言,否则将字符数乘以4将是一个明显的高估。


7
对您来说,什么是“放荡的语言”?现实世界中会存在任何语言,或者在世界上不同语言之间切换的文本?如果UTF-8-to-String函数的开发人员进行了过度分配并在实际转换后缩小了结果的大小,是否应该选择2、3或4作为乘数?
Daniel Marschall 2014年

1
@rinntech是“神秘语言”,他表示一种语言,具有很多高价值的unicode字符(此列表底部附近的内容:unicode-table.com/en/sections)。如果必须分配过多,请选择4。您可以进行两次遍历,一次查看需要多少字节并分配,然后再进行编码。这可能比分配约4倍的所需RAM更好。
matiu 2014年


19
CJKV字符大部分占用3个字节(有些稀有/古体字符占用4个字节),称它们为奥义有点儿麻烦(仅中国就占世界人口的20%...)。
Tgr

3
为什么以前是6时限制为4?是什么使我们无法继续执行标准,并没有提供字符的前导字节111111112^(6*7)位空间?
亚伦·弗兰克

31

没有进一步的上下文,我想说的是,UTF-8中字符的最大字节数为

答案:6个字节

接受的答案的作者正确地指出这是“原始规范”。这通过RFC-2279 1是有效的。正如J. Cocoe在下面的评论中指出的那样,此情况在2003年通过RFC-3629 2进行了更改,RFC-3629 2将UTF-8的编码范围限制为21位,可以使用四个字节的编码方案进行处理。

如果覆盖所有unicode,则回答:4个字节

但是,在Java <= v7中,他们谈论使用UTF-8表示unicode的最大3字节吗?这是因为原始的unicode规范仅定义了基本的多语言平面(BMP),即它是unicode的较旧版本或现代unicode的子集。所以

如果仅代表原始unicode,则回答BMP:3个字节

但是,OP谈论的是另一种方式。不是从字符到UTF-8字节,而是从UTF-8字节到字节表示的“字符串”。也许接受的答案的作者是从问题的上下文中得出的,但这不一定是显而易见的,因此可能使对此问题的普通读者感到困惑。

从UTF-8到本机编码,我们必须研究如何实现“字符串”。某些语言(例如Python> = 3)将用整数代码点表示每个字符,这使每个字符4个字节= 32位可以覆盖我们需要的unicode的21个字节,但有些浪费。为什么不完全是21位?因为当它们按字节对齐时,事情会更快。诸如Python <= 2和Java之类的某些语言使用UTF-16编码表示字符,这意味着它们必须使用代理对来表示扩展的unicode(不是BMP)。无论哪种方式,最大长度仍为4个字节。

如果要使用UTF-8,请回答->本机编码:4个字节

因此,最后的结论4是最常见的正确答案,所以我们说对了。但是,里程可能会有所不同。


4
“根据维基百科,这仍然是当前正确的规范”-不再。在您撰写此书(4月2日编辑)后不久,Wikipedia的UTF-8文章进行了更改,以阐明6个字节的版本不属于当前(2003年)UTF-8规范的一部分。
J. Cocoe '16年

“但是,在Java <= v7中,他们谈论使用UTF-8表示unicode的最大3字节?这是因为原始的unicode规范仅定义了基本的多语言平面” –这可能是原始原因,但是这不是全部。Java使用“修改后的UTF-8”,而修改之一是“使用其自己的2×3字节格式”,而不是“标准UTF-8的4字节格式”(用他们的话)。
J.可可

1
没有分配超过10FFFF(刚好超过一百万)限制的代码点,并且许多UTF8实现从未实现超过4个字节的序列(并且只有3个,例如MySQL),因此我认为将每个限制硬限制为4个字节是安全的即使考虑与较早实现的兼容性,也可以使用codepoint。您只需要确保在途中丢弃任何无效的东西即可。请注意,在可能的情况下,matiu建议在计算出精确的字节长度后进行分配。
thomasrutter

2
“ ... [U] nicode最多可以表示x10FFFF个代码点。因此,包括0在内,这意味着我们可以使用以下字节来做到这一点:F FF FF,即两个半字节或20位。” 我相信这有点不正确。从0x0到0x10FFFF的代码点数将是0x110000,可以用1F FF FF或21位表示。0x110000数字对应于每个0x10000代码点的17个平面
Neuromer

2
PSA:维基百科不是一个真实的来源。查看文章的实际参考。
Nyerguds

0

支持US-ASCII(标准英语字母编码)的最大字节数为1。但是随着时间的流逝,将文本限制为英语变得越来越不可取或不切实际。

Unicode旨在代表所有人类语言的标志符号以及多种具有各种渲染特征的符号。UTF-8是一种有效的Unicode编码,尽管它仍然偏向英语。UTF-8是自同步的:通过在任一方向上扫描定义明确的位模式,可以轻松识别字符边界。

虽然每个UTF-8字符的最大字节数是3,以仅支持平面0(基本多语言平面(BMP))的2字节地址空间,在某些应用程序中它可以被接受为最低限度的支持,但它是4,则仅用于支持Unicode的所有当前17个平面(截至2019年)。应当注意,许多流行的“表情符号”字符很可能位于16平面中,这需要4个字节。

但是,这仅适用于基本字符字形。还有各种修饰符,例如使重音符号出现在前一个字符上,并且还可以将任意数量的代码点链接在一起以构造一个复杂的“字形”。因此,在现实世界的编程中,每个字符使用或假设使用固定的最大字节数最终可能会给您的应用程序带来麻烦。

这些考虑意味着UTF-8字符串在处理之前不应该“扩展”为固定长度的数组,这有时是可以做到的。相反,应使用专门为UTF-8设计的字符串函数直接进行编程。


注意:关于不使用固定宽度字符数组的段落是我自己的看法。我愿意编辑此答案以回应评论。
David Spector
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.