Unicode编码
我有一个问题,如果程序事先不知道所使用的编码,那么它们如何解析字符串 据我所知,UTF-8编码存储1字节的ASII字符,以及最多6(我认为是6)字节的所有其他字符。因此,例如,两个空格将作为0x2020存储在内存中 那么,一个程序如何才能确定这个字符串和使用UTF-16编码的字符串“0x2020”之间的差异呢?UTF-16编码对应于一个字符,这个字符显然与数学中有时用来表示运算符伴随的符号相似(我只是查了一下)Unicode编码,unicode,Unicode,我有一个问题,如果程序事先不知道所使用的编码,那么它们如何解析字符串 据我所知,UTF-8编码存储1字节的ASII字符,以及最多6(我认为是6)字节的所有其他字符。因此,例如,两个空格将作为0x2020存储在内存中 那么,一个程序如何才能确定这个字符串和使用UTF-16编码的字符串“0x2020”之间的差异呢?UTF-16编码对应于一个字符,这个字符显然与数学中有时用来表示运算符伴随的符号相似(我只是查了一下) 似乎解析器总是必须事先知道字符串的编码。如果是,这在实践中是如何实施的?每个字符串前
似乎解析器总是必须事先知道字符串的编码。如果是,这在实践中是如何实施的?每个字符串前面是否有一个字节告诉解析器使用了什么编码或其他什么?一般来说,仅根据可以表示文本的字节流,不可能确切知道使用了什么编码。然而,如果在某个地方有一个编码,您至少可以使用它作为使用什么编码的提示 但是,如果文本的生产者和消费者之间没有提示或某种元数据契约/交换,您就不能100%确定。你可以,但如果你最终失败了 如果您真的想确定,请在文本的生产者和消费者之间建立某种协议或契约,以便了解文本和编码方案。您可以对编码方案进行硬编码(例如,您的程序可能会解析UTF-8,而只解析UTF-8),或者确保文本的生产者始终预先添加字节顺序标记或专门设计的头字节,以传达编码方案 该语言是否总是以某种编码方式存储字符串,以便 显示函数可以安全地假定字符串已编码, 比如说,使用UTF-8 英语取决于语言 在C#中,是的。
char
由(8.2.1)定义为UTF-16代码单元,因此字符串始终为UTF-16
在中,字符串是具有关联的编码的字节数组
但在C等前Unicode语言(以及PHP等设计糟糕的后Unicode语言)中,字符串只是一个没有编码信息的字节数组。你必须依靠传统。编写一个既使用假定UTF-8字符串的库,又使用假定windows-1252字符串的库的程序是一个非常有趣的经历
与所有语言同样相关的一个问题是:如何确定包含编码文本的字节数组的编码?有几种不同的方法:
编码声明。
在使用MIME类型(特别是SMTP和HTTP)的协议中,可以声明内容类型:text/html;字符集=UTF-8
。在HTML中,您可以使用
或更新的
。在XML中,有
。在中,有#-*-编码:UTF-8-*-
不幸的是,这些声明并不总是准确的。而且它们对于本地存储的纯.txt
文件根本不可用,因此必须使用不同的方法
字节顺序标记(BOM)
将特殊字符放在文件的开头可以区分各种UTF编码
但它不适用于传统编码,如ISO-8859-x或Windows-125x,也不总是与UTF-8一起使用
验证
有些编码有严格的规则,规定什么是有效字符串。最著名的是UTF-8,它严格区分前导/尾随字节,禁止“超长”编码,等等。UTF-32更容易识别,因为Unicode限制为17个“平面”,这意味着每个代码单元必须具有格式00{00-10}xx xx xx(或xx-xx{00-10}00表示小尾端)
所以,如果文本验证为UTF-8或UTF-32,您可以安全地假设它是。有可能出现误报,但非常低
然而,这种方法不适用于UTF-16,因为UTF-16的假阳性率太高。(偶数长度字节数组无效UTF-16的唯一方法是包含未配对的代理项,或U+FFFE或U+FFFF。)
统计分析
使用各种语言/编码组合的字符频率表。这是所使用的方法(与BOM和验证相结合)
退回默认编码
当所有其他操作都失败时,假设ISO-8859-1、windows-1252或编码。默认值
如果您有一个表示字符数据的字节序列,但不知道编码,则表示您有编码错误。Unicode编码有一些技巧,比如字节顺序标记,但这些技巧并没有(也不可能)被普遍采用。您写道,“我认为它是6个字节。”最初的UTF-8规范允许使用最多6个字节来表示32位宽的代码点,事实上,它可以扩展到更多。但是,由于UTF‑16设计限制,实际使用UTF‑8算法的被“人为”限制为仅21位的代码点,因此不需要超过4个字节来编码任何高达U+10FFFF的标量值,display函数可能需要知道字符串的编码。在这种情况下,显示函数如何确定字符编码?该语言是否总是以某种编码方式存储字符串,以便显示函数可以安全地假定字符串是使用UTF-8编码的?@Jonathan Gleason-不同的语言处理字符串的方式不同-。不同的平台/容器/API可能会添加它们自己的条件/约束。@Jonathan Gleason:这当然是特定于平台的。例如,Windows API中的CreateWindowExW()
函数需要UTF-16编码的字符串,不管怎样