来自 NSUTF8StringEncoding 的 6 字节表情符号

6 byte emojis from NSUTF8StringEncoding

我对以 UTF8 编码的表情符号的字节表示感到困惑。我的理解是UTF8字符大小可变,最多4个字节。

当我在 iOS 13 上以 UTF8 编码 ❤️ 表情符号时,我得到了 6 个字节:

NSString* heartEmoji = @"❤️";
NSData* utf8 = [heartEmoji dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@", utf8); // {length = 6, bytes = 0xe29da4efb88f}

如果我恢复操作,只消耗前 3 个字节,我得到一个 unicode 心:

BYTE bytes[3] = { 0 };
[utf8 getBytes:bytes length:3];
NSString* decoded = [[NSString alloc] initWithBytes:bytes length:3 encoding:NSUTF8StringEncoding];
NSLog(@"%@", decoded); // ❤

请注意,我以心脏为例;我尝试了很多表情符号,大多数是 UTF8 中的 4 个字节,但有些是 6 个。

我对 UTF8 的假设有误吗?如何将 4 个字节的所有表情符号表示为 UTF8?

My understanding is that UTF8 characters are variable in size, up to 4 bytes.

这不太正确。一个 UTF8 code point 最多 4 个字节。但是一个字符(特别是一个扩展的字素簇)由于组合字符可能会更长。最少几十个字节,在最极端的情况下是无限的。有关有趣的示例,请参阅

在您的示例中,您的表情符号是 HEAVY BACK HEART (U+2764),然后是 VARIATION SELECTOR-16 (U+FE0F),表示它应该是红色的。 UTF-8 需要三个字节来编码每个代码点。