从UTF8转换为UTF16 LE的概念c编程中的数学运算

时间:2019-05-15 12:20:41

标签: c embedded

我想知道从UTF8转换为UTF16 LE的概念

例如 输入序列E3 81 82 输出序列是42 30

此转换中实际的算术运算是什么。(我不想调用内置库)

1 个答案:

答案 0 :(得分:1)

基本上,Unicode是一种在一个连续的代码空间中表示尽可能多的符号的方法,每个符号的代码通常称为“ 代码点”。 UTF-8 UTF-16 只是以一个或多个八位位组(UTF-8)或16位字(UTF-16)编码和表示这些代码点的方式),则最新版本可以用 little-endian (“最低有效优先”或“ Intel字节顺序”)或 big-endian (“最优先顺序”或“摩托罗拉字节顺序”),它为我们提供了两种变体:UTF-16LE和UTF-16BE。

首先需要做的是从UTF-8序列中提取代码点。 UTF-8编码如下:

0x00 ... 0x7F 编码符号“原样”,它对应于标准ASCII符号

但是,如果设置了最高有效位(即 0x80 ... 0xFF ),则意味着这是一个由几个字节组成的序列,它们全部对代码点进行编码

范围 0xC0 ... 0xFF 中的

个字节在该序列的第一个位置,以二进制表示,它们是:

  • 0b 110xxxxx -后面还有1个字节,xxxxx是代码点的5个最高有效位
  • 0b 1110xxxx -再加上2个字节,xxxx是代码点的4个最高有效位
  • 0b 11110xxx -另外3个字节...
  • 0b 111110xx -另外4个字节...

在Unicode标准中没有定义代码点,目前这些代码点需要超过5个UTF-8字节。

后续字节的范围为 0x80 ... 0xBF (即0b 10xxxxxx ),并从代码点值开始编码接下来的6位(从最高有效到最低有效)。

因此,请看您的示例:E3 81 82

  • 0xE3 == 0b 1110 0011 表示此代码点中将有2个字节,而 0011 -是其中的最高有效位
  • 0x81 == 0b 10 000001 表示这不是代码点序列中的第一个字节,并且对接下来的6位进行编码: 000001
  • 0x82 == 0b 10 000010 表示这不是代码点序列中的第一个字节,并且对接下来的6位进行编码: 000010

即结果将为 0011 000001 000010 == 0x3042

UTF-16 的工作方式相同。最常见的代码点只是按“原样”编码,但是一些较大的值打包在所谓的“代理对”中,它们是两个16位字的组合:

    范围 0xD800 ... 0xDBFF 中的
  • 个值代表它们中的第一个,它的低10位用于编码所得代码点的10个最高有效位。
  • 范围 0xDC00 ... 0xDFFF 中的值表示第二个,其低位编码所得代码点的10个最低有效位。

大于0xFFFF(明显)和0xD800 ... 0xDFFF的值都需要代理对-但是此范围在Unicode标准中为代理对保留,并且不能有此类符号。

因此,在我们的示例中, 0x3042 不会达到该范围,因此仅需要一个16位字。

因为在您的示例中给出了UTF-16LE(小尾数)变体,所以这意味着,在字节序列中,第一个将是该字的最低有效一半。即

0x42 0x30