Ruby 1.9.3为什么" \ x03" .force_encoding(" UTF-8")得到\ u0003,但" \ x03" .force_encoding(" UTF-16")获得" \ x03"

时间:2014-03-13 02:16:01

标签: ruby-on-rails ruby encoding utf-8 utf-16

Ruby 1.9.3

irb(main):036:0* "\x03".force_encoding("UTF-16")
=> "\x03"
irb(main):040:0* "\x03".force_encoding("UTF-8")
=> "\u0003"

为什么“\ x03”.force_encoding(“UTF-8”)是\ u0003而“\ x03”.force_encoding(“UTF-16”)以“\ x03”结束,我认为应该是另一个一路走来?

1 个答案:

答案 0 :(得分:2)

因为"\x03"不是UTF-16中的有效代码点,而是UTF-8中的有效代码点(ASCII 03,ETX,文本结尾)。您必须使用至少两个字节来表示UTF-16中的unicode代码点。

这就是为什么"\x03"可以在UTF-8中被视为unicode \u0003而在UTF-16中不被视为。{/ p>

要在UTF-16中表示"\u0003",您必须使用两个字节00 0303 00,具体取决于字节顺序。这就是我们需要在UTF-16中指定字节顺序的原因。对于big-endian版本,字节序列应为

FE FF 00 03

对于little-endian,字节序列应为

FF FE 03 00

字节顺序标记应出现在字符串的开头或文件的开头。

从Ruby 1.9开始,String只是一个字节序列,具有特定的编码作为标记。 force_encoding是一种更改编码标记的方法,它不会影响字节序列。您可以通过检查"\x03".force_encoding("UTF-8").bytes来验证这一点。

如果你看到"\u0003",那并不意味着你得到一个用两个字节00 03表示的字符串,而是一些表示Unicode代码点0003的字节在该字符串中携带的特定编码下。它可能是:

03              //tagged as UTF-8
FE FF 00 03     //tagged as UTF-16
FF FE 03 00     //tagged as UTF-16
03              //tagged as GBK
03              //tagged as ASCII
00 00 FE FF 00 00 00 03 // tagged as UTF-32
FF FE 00 00 03 00 00 00 // tagged as UTF-32