libiconv:在UTF-8/UTF-16/UTF-32之间转换时目标字节长度的安全估计?

libiconv:在UTF-8/UTF-16/UTF-32之间转换时目标字节长度的安全估计?,c,unicode,utf-8,utf-16,libiconv,C,Unicode,Utf 8,Utf 16,Libiconv,关于Unicode代码单位、代码点等有很多信息,但我对使用字节流(需要)转换组合字符、图形等仍然有点模糊 目前,我只对使用libconv的iconv()在UTF-8/UTF-16/UTF-32之间进行转换感兴趣,它需要源缓冲区和目标缓冲区的字节长度作为参数 问题:是否有一种安全的方法可以根据源缓冲区的已知字节长度快速计算目标缓冲区的最大可能字节长度 例如,使用已知的u16byteslen(不包括0x0000终止,如果有)将u16buf转换为u8buf。在最坏的情况下,UTF-16源缓冲区中每个代

关于Unicode代码单位、代码点等有很多信息,但我对使用字节流(需要)转换组合字符、图形等仍然有点模糊

目前,我只对使用libconv的
iconv()
在UTF-8/UTF-16/UTF-32之间进行转换感兴趣,它需要源缓冲区和目标缓冲区的字节长度作为参数

问题:是否有一种安全的方法可以根据源缓冲区的已知字节长度快速计算目标缓冲区的最大可能字节长度

例如,使用已知的
u16byteslen
(不包括0x0000终止,如果有)将
u16buf
转换为
u8buf
。在最坏的情况下,UTF-16源缓冲区中每个代码点将有1个双字节单元,对应于UTF-8目标缓冲区中每个代码点4个单字节单元。这是否足以安全地假设UTF-8目标缓冲区的长度不能超过
2*u16lenbytes

实际上我已经尝试过了,而且似乎很管用,但我不确定我是否遗漏了涉及组合字符和字符集的角落案例。我的怀疑来自于我对这些东西如何通过这3种不同编码转换的无知。我的意思是,一个图形有可能需要3个UTF-16码点,但转换时需要10个UTF-8码点吗

在这种情况下,加倍
u16lenbytes
是不够的,对吗?如果是的话,有没有其他直接的方法来预先计算目标缓冲区的最大长度

问题:是否有一种安全的方法可以根据源缓冲区的已知字节长度快速计算目标缓冲区的最大可能字节长度

至UTF-8 至UTF-16 至UTF-32 来自UTF-8 ×2 ×4 来自UTF-16 ×1 ½ ×1 来自UTF-32 ×1 ×1 问题:是否有一种安全的方法可以根据源缓冲区的已知字节长度快速计算目标缓冲区的最大可能字节长度

至UTF-8 至UTF-16 至UTF-32 来自UTF-8 ×2 ×4 来自UTF-16 ×1 ½ ×1 来自UTF-32 ×1 ×1
可以对Unicode代码点进行编码:

  • UTF-8:1、2、3或4字节
  • UTF-16:2或4字节
  • UTF-32:4字节
  • (过时):UCS-2:2字节(但对于某些代码点,它需要两个代理)
因此,作为第一个估计,如果UTF-16的长度以字节为单位,则可以使用以下公式:

byte_len_utf8 = 4 * byte_len_utf16 / 2
但这不是一个好方法:我们更清楚:只有当UTF-16是4字节长度时,UTF-8才是4字节长度。所以我们有两种情况:
4*len/4
3*len/2


因此,如果我们在第一个公式中分配双字节(如您所想),在第二个公式中,最大值仅为字节数的1.5倍。对于中文/日文/韩文,您处于这样的代码点区域。

可以对Unicode代码点进行编码:

  • UTF-8:1、2、3或4字节
  • UTF-16:2或4字节
  • UTF-32:4字节
  • (过时):UCS-2:2字节(但对于某些代码点,它需要两个代理)
因此,作为第一个估计,如果UTF-16的长度以字节为单位,则可以使用以下公式:

byte_len_utf8 = 4 * byte_len_utf16 / 2
但这不是一个好方法:我们更清楚:只有当UTF-16是4字节长度时,UTF-8才是4字节长度。所以我们有两种情况:
4*len/4
3*len/2


因此,如果我们在第一个公式中分配双字节(如您所想),在第二个公式中,最大值仅为字节数的1.5倍。对于中国人/日本人/韩国人来说,你处于这样一个代码点区域。

比我快,但这正是我要写的,除了第三段。当从一个Unicode编码转换到另一个Unicode编码时,iconv不做任何关于组合字符、规范化等的事情;它只是在一个码点一个码点的基础上重新编码。@TEDLYNGOM:根据Unicode标准,在解码UTF-16时,BOM是可选的。然而,该标准要求不带BOM的UTF-16文本被解释为大端。参见§3.10。@TedLyngmo,是的,我是指你关于无BOM UTF-16文本的评论,回答说AFAIK无BOM仅适用于UTF-8(而非UTF-16)显然这太疯狂了,所以从实用角度来看,任何编码为UTF-16的软件都会包含BOM。与iconv类似。@DietrichEpp UTF-16没有BOM表的文本,如果发送方没有贴上显示UTF-16LE或UTF-16BE的标签,则应解释为big-endian。见RFC 2781§4.3。当端点已知时,这不成立。例如,在Windows API中,UTF-16实际上始终是UTF-16LE。请告诉我,但这正是我要写的内容,只是我将以第三段开头。当从一个Unicode编码转换到另一个Unicode编码时,iconv不做任何关于组合字符、规范化等的事情;它只是在一个码点一个码点的基础上重新编码。@TEDLYNGOM:根据Unicode标准,在解码UTF-16时,BOM是可选的。然而,该标准要求不带BOM的UTF-16文本被解释为大端。参见§3.10。@TedLyngmo,是的,我是指你关于无BOM UTF-16文本的评论,回答说AFAIK无BOM仅适用于UTF-8(而非UTF-16)显然这太疯狂了,所以从实用角度来看,任何编码为UTF-16的软件都会包含BOM。与iconv类似。@DietrichEpp UTF-16没有BOM表的文本,如果发送方没有贴上显示UTF-16LE或UTF-16BE的标签,则应解释为big-endian。见RFC 2781§4.3。当端点已知时,这不成立。例如,在Windows API中,UTF-16实际上始终是UTF-16LE。从一个UTF方案转换到另一个UTF方案不应改变任何代码点。@MarkRansom:Using
iconv
,转换为