我对用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?
我的理解是UTF8字符的大小是可变的,最多4个字节。
这不太正确。 UTF8 代码点最多4个字节。但是由于组合字符,字符(特别是扩展的字素簇)可能更长。最少几十个字节,在最极端的情况下不限制。有关有趣的示例,请参见Why are emoji characters like 👩👩👧👦 treated so strangely in Swift strings?。
在您的示例中,您的表情符号是HEAVY BACK HEART(U + 2764),后跟VARIATION SELECTOR-16(U + FE0F),表示它应为红色。 UTF-8需要三个字节来对每个代码点进行编码。