为什么 emoji 有两个不同的 utf-8 编码?如何从 utf-8 转换表情符号,在 ios 中使用 NSString?

Why does emoji have two different utf-8 codes? How to convert emoji from utf-8 , use NSString in ios?

我们发现一个问题,一些表情符号有两个 utf-8 代码,例如:

emoji   unicode    utf-8                another utf-8
      U+1F601    \xf0\x9f\x98\x81     \xed\xa0\xbd\xed\xb8\x81

但是ios语言无法解码其他类型的utf-8,所以当我从utf-8解码字符串时导致错误。


在我找到的所有文档中,我只能找到一种表情符号的 utf-8 代码,找不到另一种。

我参考的文件包括:

emoji code link

whole utf-8 code link

但是在网页工具bianma中,这两种utf-8编码都可以正确转换成emoji


那么,我的问题是:

  1. 为什么一个表情符号有两种utf-8编码?

  2. 哪里有包含这两种utf-8编码的文档?

  3. 如何使用 ios 语言中的 NSString 从 utf-8 正确转换字符串?

0xF0, 0x9F, 0x98, 0x81

是 U+1F601 的正确 UTF-8 编码。

0xED, 0xA0, 0xBD, 0xED, 0xB8, 0x81

不是有效的 UTF-8 序列(*)。它真的应该被拒绝; iOS 这样做是正确的。

这是变码工具中的一个错误:convertUtf8BytesToUnicodeCodePoints 函数比 RFC 3629.

中指定的算法更宽松地接受输入。

这只发生在 return 工作字符串中,因为该工具是用 JavaScript 编写的。将上述字节序列解码为伪造的代理代码点序列 U+D83D,U+DE01 后,它使用直接代码点到代码单元映射将其转换为 JavaScript 字符串 \uD83D\xDE01.因为这是在 UTF-16 字符串中编码的正确方法,所以它似乎有效。

(*: 它 一个有效的 CESU-8 序列,但该编码只是“为了与写得不好的历史工具兼容而伪造的破损编码”,通常应该避免.)

你通常不会遇到这样的序列;它通常不值得迎合,除非你有这种格式错误的数据的特定来源,而你无力修复。

这对我在 php 有用,可以用表情符号向电报机器人发送消息:

$message_text = " \xf0\x9f\x98\x81 ";