gpt4 book ai didi

java - 为什么UTF-8 BOM字节efbbbf可以换成\ufeff?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:31:31 26 4
gpt4 key购买 nike

byte order mark (BOM)对于 UTF-8EF BB BF,如 section 23.8 of the Unicode 9 中所述规范(搜索“签名”)。

Java 中的许多解决方案都只是简单的一行代码:

 replace("\uFEFF", "")

我不明白为什么会这样。

这是我的测试代码。我在调用 String#replace 后检查了二进制文件,发现 EF BB BF 确实被删除了。看这个code run live at IdeOne.com .

太神奇了。为什么会这样?

@Test
public void shit() throws Exception{
byte[] b = new byte[]{-17,-69,-65, 97,97,97};//EF BB BF 61 61 61
char[] c = new char[10];
new InputStreamReader(new ByteArrayInputStream(b),"UTF-8").read(c);
byte[] bytes = new StringBuilder().append(c).toString().replace("\uFEFF", "").getBytes();//
for(byte bt: bytes){//61 61 61, we can see EF BB BF is indeed removed
System.out.println(bt);
}
}

最佳答案

原因是 unicode 文本应以字节顺序标记开头(UTF-8 除外,它不是推荐强制性[1])。

来自维基百科

The byte order mark (BOM) is a Unicode character, U+FEFF BYTE ORDER MARK (BOM), whose appearance as a magic number at the start of a text stream ...
...
The BOM is encoded in the same scheme as the rest of the document ...

这意味着这个特殊字符 (\uFEFF) 也必须以 UTF-8 编码。

UTF-8 可以将 Unicode 代码点编码为一到四个字节。

  • 可以用7位表示的码点编码在一个字节中,最高位始终为零0xxx xxxx
  • 所有其他代码点根据位数以多个字节编码,第一个字节的左侧设置位表示用于编码的字节数,例如110x xxxx 表示编码由两个字节表示,连续字节始终以 10xx xxxx 开头(x 位可用于代码点)

U+0000 - U+007F范围内的码点可以用一个字节编码。
U+0080 - U+07FF 范围内的代码点可以用两个字节编码。U+0800 - U+FFFF 范围内的代码点可以用三个字节编码。

详细解释在Wikipedia

对于 BOM,我们需要三个字节。

hex    FE       FF
binary 11111110 11111111

用UTF-8编码

pattern for three byte encoding 1110 xxxx  10xx xxxx  10xx xxxx
the bits of the code point 1111 11 1011 11 1111
result 1110 1111 1011 1011 1011 1111
in hex EF BB BF

EF BB BF 听起来很熟悉。 ;-)

字节序列 EF BB BF 就是以 UTF-8 编码的 BOM。

由于字节顺序标记对 UTF-8 没有意义,因此在 Java 中未使用。

将 BOM 字符编码为 UTF-8

jshell> "\uFEFF".getBytes("UTF-8")
$1 ==> byte[3] { -17, -69, -65 } // EF BB BF

因此,当读取文件时,字节序列被解码为 \uFEFF

用于编码,例如UTF-16 添加BOM

jshell> " ".getBytes("UTF-16")
$2 ==> byte[4] { -2, -1, 0, 32 } // FE FF + the encoded SPACE

[1] 引自:http://www.unicode.org/versions/Unicode9.0.0/ch23.pdf

Although thereare never any questions of byte order with UTF-8 text, this sequence can serve as signaturefor UTF-8 encoded text where the character set is unmarked. As with a BOM in UTF-16,this sequence of bytes will be extremely rare at the beginning of text files in other characterencodings.

关于java - 为什么UTF-8 BOM字节efbbbf可以换成\ufeff?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54247407/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com