找回密码
 快速注册
搜索
查看: 61|回复: 4

UTF8编码5位数 疑问

[复制链接]

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2022-7-18 07:41 |阅读模式
本帖最后由 hbghlyj 于 2022-7-23 20:49 编辑

  1. ٦
复制代码
变成٦
码点666
  1. 晦
复制代码
变成
码点6666
  1. 񦙦
复制代码
变成񦙦
码点66666
在Chrome上显示为方块,而在Firefox上显示为一个方块里面写着066666,效果:
Screenshot 2022-07-18 at 01-19-27 HTML实体 16进制 5位数 疑问 - 测试区 - 悠闲数学.png
在控制台看一下码点:
Screenshot 2022-07-17 at 18-23-24 A2 Complex Analysis Lecture 2.png
它是两个字符, 第一个字符的编码是d959, 第二个字符的编码是de66.
这两个编码怎么来的呢?

730

主题

1万

回帖

9万

积分

积分
93623
QQ

显示全部楼层

kuing 发表于 2022-7-20 16:22
其实还是一个字符 U+66666,那两个字节就是它的 UTF-16 编码。

今天想了解多一点 emoji 的东西,读了 这篇文章,看到了“UTF-16 编码”部分就想起了这帖,根据那里的换算规则就可以算出 U+66666 的 UTF-16 编码就是 \ud959\ude66。

照你图上所给出的二进制,也可以这样直观一点计算:
66666$_{16}$ = 0110 0110 0110 0110 0110$_2$
减去 10000$_{16}$ 变成
0101 0110 0110 0110 0110$_2$
从中间切开成两组
01 0101 1001$_2$ 和 10 0110 0110$_2$
分别加上 D800$_{16}$ 和 DC00$_{16}$(即 1101 1000 0000 0000$_2$ 和 1101 1100 0000 0000$_2$)即得
1101 1001 0101 1001$_2$ 和 1101 1110 0110 0110$_2$(即 D959$_{16}$ 和 DE66$_{16}$)

413

主题

1558

回帖

1万

积分

积分
11498

显示全部楼层

abababa 发表于 2022-7-20 20:26
kuing 发表于 2022-7-20 16:22
其实还是一个字符 U+66666,那两个字节就是它的 UTF-16 编码。

今天想了解多一点 emoji 的东西,读了 这篇 ...

链接里讲UTF8的那部分,我觉得不够详细,发一段网友以前给我讲的:
UTF-8编码规则:
Unicode 码点范围(16 进制)                UTF-8 模板(二进制)
0000 0000 —— 0000 007F                0xxxxxxx
0000 0080 —— 0000 07FF                110xxxxx 10xxxxxx
0000 0800 —— 0000 FFFF                1110xxxx 10xxxxxx 10xxxxxx
0001 0000 —— 001F FFFF                11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
0020 0000 —— 03FF FFFF                111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
0400 0000 —— 7FFF FFFF                1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

例如 一 的 Unicode 码点是 U+4E00,需要使用第三个模板,模板格式为 1110xxxx 10xxxxxx 10xxxxxx,需要 3 字节。从 U+4E00 = 01001110 00000000 的最低位开始,依次替代模板中的 x,就得到 一 的 UTF-8 编码是 11100100 10111000 10000000。读取时,如果一个字节以 0 开头,表示这是一个 ASCII 字符 (00-7F)。如果一个字节以 11 开头,说明它是一个字符的首字节,其中连续的 1 的数量表示此字符占用的字节数,例如 110xxxxx 以 11 开头,连续 2 个 1,说明它是双字节 UTF-8 字符的首字节,接下来还要再读取一个字节。如果一个字节以 10 开头,说明它不是首字节,需要向前查找才能得到当前字符的首字节。

413

主题

1558

回帖

1万

积分

积分
11498

显示全部楼层

abababa 发表于 2022-7-20 20:32
abababa 发表于 2022-7-20 20:26
链接里讲UTF8的那部分,我觉得不够详细,发一段网友以前给我讲的:
UTF-8编码规则:
Unicode 码点范围(16 ...

链接里后面说的“这是UTF-16和GBK无法做到的”,应该就是指这个。假设UTF-16是3456 7890 ABCD EFAB,代表两个汉字。然后本来3456 7890代表一个汉字,但是如果3456这个字节坏了,没传过来,那么读到的就是7890 ABCD EFAB……,这样就会把7890 ABCD组合在一起当成一个汉字,造成后面所有的字都错了。

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

 楼主| hbghlyj 发表于 2022-8-1 04:09
mb_strpos基于字符数执行一个多字节安全的 strpos() 操作。
什么是多字节安全(multi-byte safe)? 见StackOverflow
When you are dealing with unicode characters, it is not safe to assume that all the characters just take a single byte or char (java). So when reading or parsing a string, you need to take this into consideration.

手机版|悠闲数学娱乐论坛(第3版)

GMT+8, 2025-3-4 16:01

Powered by Discuz!

× 快速回复 返回顶部 返回列表