为什么感觉 utf8 的编码没有对上?

2022-05-17 22:06:13 +08:00
 amiwrong123

先看第一行:

再看第二行:

1772 次点击
所在节点    程序员
8 条回复
wudicgi
2022-05-17 22:23:11 +08:00
可能是因为这个,有的字节是不能出现的

https://zh.wikipedia.org/zh-cn/UTF-8

根据这种方式可以处理更大数量的字符。原来的规范允许长达 6 字节的序列,可以覆盖到 31 位(通用字符集原来的极限)。尽管如此,2003 年 11 月 UTF-8 被 RFC 3629 重新规范,只能使用原来 Unicode 定义的区域,U+0000 到 U+10FFFF 。根据这些规范,以下字节值将无法出现在合法 UTF-8 序列中:
编码(二进制) 编码(十六进制) 注释
1100000x C0, C1 过长编码:双字节序列的头字节,但码点 <= 127
1111111x FE, FF 无法达到:7 或 8 字节序列的头字节
111110xx
1111110x F8, F9, FA, FB, FC, FD 被 RFC 3629 规范:5 或 6 字节序列的头字节
11110101
1111011x F5, F6, F7 被 RFC 3629 规范:码点超过 10FFFF 的头字节
wudicgi
2022-05-17 22:25:33 +08:00
去掉 0xC0, 0xC1
(2^5-2)*(2^6) = 1920 = (0x7FF-0x80)+1 就能对上了
amiwrong123
2022-05-17 22:40:34 +08:00
@wudicgi #2
好像懂了,虽然实际上 110x xxxx 和 10xx xxxx 可以把 0x0000 ~ 0x07FF 都编码进去(而不只是 0x0080 ~ 0x07FF )。
但设计上,不允许让 属于第一行的 0x00 ~ 0x7F 这个范围 的码点,被第二行 编码进去。

这么看的话,第三行也是一样:
- 有 16 个自由变化 bit ,所以实际上可以把 0x0000~0xFFFF 都给编码进去的。但设计上,不允许让 0x0000~0x07FF 的码点被编码进第三行。
az467
2022-05-18 00:07:55 +08:00
主要是为了禁止 overlong encoding ,没必要用 N+M 个 byte 表示 N 个 byte 就能表示的东西。
顺便配合规范,总共就 10FFFF 个码点,不支持 4 bytes 以上的格式了。
SoloCompany
2022-05-18 00:17:13 +08:00
因为 utf8 是一个安全的编码,确保在任意地方截断后都能 recover
举一个反例,gb 编码就不是安全的编码,在半字中间阶段会导致所有编码全部错位
更差的例子是 big5 ,允许使用 ascii 字符作为编码的一部份,导致一些 markup 语言(包括 ini )直接出错
3dwelcome
2022-05-18 00:54:42 +08:00
"因为 utf8 是一个安全的编码,确保在任意地方截断后都能 recover"
感觉这个说法不对,就算把 110x xxxx 和 10xx xxxx 的 2^11 种取值用完,也是可以正常 recover 的。

还是赞同一楼的说法,既然 utf8 映射 unicode 有一定冗余空间,那就没必要全部用完。保留出一些头字节和 BOM ,也是完全没问题的。
fourthLALA
2022-05-18 01:00:57 +08:00
为啥我完全没理解。。。0x07FF − 0x0080 = 77f ,再加上 1 ,不就是 2^11 次发吗。
fourthLALA
2022-05-18 01:04:41 +08:00
我傻逼了,请无视我

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/853559

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX