给定UTF-16大小的最大UTF-8字符串大小

问题描述 投票:1回答:1

确定编码给定数量的UTF-16代码单元所需的最大UTF-8字节数(即C#/ .NET中String.Length的值)的公式是什么?

我看到3种可能性:

1)# of UTF-16 code units x 2

2)# of UTF-16 code units x 3

3)# of UTF-16 code units x 4

UTF-16代码点由1或2个代码单元表示,因此我们只需要考虑填充了一个或另一个的字符串的最坏情况。如果一个UTF-16字符串完全由2个代码单元代码点组成,那么我们知道UTF-8表示最多将是相同的大小,因为代码点在两个表示中最多占用4个字节,因此最坏的情况是上面的选项(1)。

因此,我不知道答案的有趣案例是单个代码单元UTF-16代码点在UTF-8表示中可能需要的最大字节数。

如果所有单个代码单元UTF-16代码点都可以用3个UTF-8字节表示,而我的直觉告诉我最有意义,那么选项(2)将是最糟糕的情况。如果有任何需要4个字节的话,那么选项(3)就是答案。

有谁有洞察哪个是正确的?我真的希望(1)或(2)因为(3)会让事情变得更难:/

UPDATE

我不是UTF专家,但是从我可以收集到的信息来看,UTF-16在单个代码单元中对BMP中的所有字符进行编码,而所有其他平面都以2个代码单元进行编码。

似乎UTF-8可以在3个字节内编码整个BMP,并使用4个字节来编码其他平面。

因此在我看来上面的选项(2)是正确的答案,这应该工作:

string str = "Some string";
int maxUtf8EncodedSize = str.Length * 3;

这看起来好像结账了吗?

c# .net utf-8 character-encoding utf-16
1个回答
3
投票

正确形成的UTF-8每个Unicode代码点最多可以有4个字节。

每个Unicode代码点,UTF-16编码的字符最多可包含2个16位序列。

基本多语言平面之外的字符(包括表情符号和添加到更新版本的Unicode中的语言)最多可以表示为21位,UTF-8格式的字符表示4字节序列,结果也占用4位UTF-16中的字节数。

但是,有些环境很奇怪。由于基本多语言平面之外的UTF-16字符最多需要2个16位序列(它们是可检测的,因为它们总是在U + D800到U + DFFF范围内的16位序列),有些错误的UTF-8实现,通常称为CESU-8,将这些UTF-8序列转换为两个3字节UTF-8序列,每个UTF-32码点总共六个字节。 (我相信一些早期的Oracle数据库实现做到了这一点,我确信它们不是唯一的)。

事物中还有一个小扳手,即一些字形被归类为组合字符,并且在确定屏幕上显示的内容时使用多个UTF-16(或UTF-32)序列,但我认为不适用在你的情况下。

根据您的编辑,您似乎正在尝试估算.Net编码转换的最大长度。字符串长度测量字符总数,它是UTF-16代码点的计数。因此,作为最坏情况的估计,我相信你可以安全地估计count(Char)* 3,因为非BMP字符将是count(Char)* 2,产生4个字节为UTF-8。

如果您想获得所代表的UTF-32代码点的总数,您应该可以执行类似的操作

var maximumUtf8Bytes = System.Globalization.StringInfo(myString).LengthInTextElements * 4;

(我的C#有点生疏,因为我在过去几年里没有使用.Net环境,但我认为这样做很有效)。

© www.soinside.com 2019 - 2024. All rights reserved.