2

我有字符“ö”。如果我查看这个 UTF-8 表,我会看到它具有十六进制值F6。如果我查看Unicode 表,我会看到“ö”具有索引E016. 如果我同时添加两者,我将得到F6. 这是二进制值 1111 0110

1)我如何从十六进制值F6到索引E016
2)我不知道F6这两个字节是怎么来的C3 B6......

因为我没有得到结果,所以我试图走另一条路。“ö”在 ISO-8859-1 中表示为“ö”。在UTF-8 表中,我可以看到 "Ã" 具有十进制值195,而 "¶" 具有十进制值182。转换为位这是1100 0011 1011 0110.

过程:

  1. 查看表格并获取字符“ö”的 unicode。从索引计算E016你得到 Unicode U+00F6

  2. 根据 wildplasser 发布的算法,您可以计算编码的 UTF-8 值C3B6.

  3. 在二进制形式中,您得到1100 0011 1011 0110对应于十进制值195182.

  4. 如果这些值被解释为ISO 8859-1(只有 1 个字节),那么你会得到“ö”。

PS:我还找到了这个链接,它显示了步骤 2 中的值。

4

2 回答 2

7

您正在使用的页面让您有些困惑。您的“UTF-8 表”或“Unicode 表”都没有为您提供 UTF-8 中代码点的值。它们都只是简单地列出字符的 Unicode 值。

在 Unicode 中,每个字符(“代码点”)都分配有一个唯一编号。该字符被ö分配了十六进制和十进制的代码点。U+00F6F6246

UTF-8 是 Unicode 的一种表示,每个 Unicode 代码点使用 1 到 4 个字节的序列。在那篇文章中描述了从 32 位 Unicode 代码点到 UTF-8 字节序列的转换——一旦你习惯了它就很容易做到。当然,计算机一直都在这样做,但是你可以用铅笔和纸轻松地做到这一点,并且在你的头脑中进行一些练习。

如果您进行该转换,您将看到U+00F6转换为 UTF-8 序列C3 B61100 0011 1011 0110二进制,这就是ö.

您问题的另一半是关于 ISO-8859-1。这是一种通常称为“ Latin-1 ”的字符编码。Latin-1 编码的数值与 Unicode 中的前 256 个代码点相同,因此öF6Latin-1 中。

在 UTF-8 和标准 Unicode 代码点 (UTF-32) 之间转换后,获得 Latin-1 编码应该很简单。但是,并非所有 UTF-8 序列/Unicode 字符都有对应的 Latin-1 字符。

请参阅优秀文章The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!),以更好地理解字符编码和它们之间的转换。

于 2011-10-26T16:02:26.923 回答
3
unsigned cha_latin2utf8(unsigned char *dst, unsigned cha)
{
if (cha <  0x80)  { *dst = cha; return 1; }
    /* all 11 bit codepoints (0x0 -- 0x7ff)
      ** fit within a 2byte utf8 char
      ** firstbyte = 110 +xxxxx := 0xc0 + (char>>6) MSB
      ** second    = 10 +xxxxxx := 0x80 + (char& 63) LSB
      */
    *dst++ = 0xc0 | (cha >>6) & 0x1f; /* 2+1+5 bits */
    *dst++ = 0x80 | (cha) & 0x3f; /* 1+1+6 bits */

return 2; /* number of bytes produced */
}

要测试它:

#include <stdio.h>
int main (void)
{
char buff[12];

cha_latin2utf8 ( buff, 0xf6);

fprintf(stdout, "%02x %02x\n"
    , (unsigned) buff[0] & 0xff
    , (unsigned) buff[1] & 0xff );

return 0;
}

结果:

c3 b6
于 2011-10-26T14:31:57.003 回答