Unicode统一码及实现方式的全面讲解

Unicode 概述

Unicode官网

         统一码(Unicode)也叫万国码、单一码,由统一码联盟开发,是一种全球通用的字符编码标准,旨在为所有语言、符号和表情符号(Emoji)分配唯一的数字编号(称为 码点,Code Point)。它的核心目标是解决传统字符集(如 ASCII、GB2312、GBK、ISO-8859 等)的兼容性问题,消除乱码,实现跨语言、跨平台的文本一致性。

关键特点:

  • 覆盖范围广:支持超过 14 万个字符(截至 Unicode 15.0)。

  • 层次化结构:将字符分为平面(Plane),每个平面包含 65,536 个码点。

    • 基本多语言平面(BMP, Plane 0):涵盖绝大多数常用字符(U+0000 到 U+FFFF)。

    • 辅助平面(Plane 1-16):包含历史文字、表情符号等(如 U+1F600 代表 😀)。

  • 唯一性:每个字符对应唯一的码点。

  • 通用性:覆盖全球所有语言和符号。

  • 兼容性:兼容传统编码(如 ASCII)。

  • 可扩展性:支持未来新增字符。

Unicode 码点基础

码点结构

  • 格式U+ + 4-6位十六进制数(如 U+1F600
  • 范围
    • BMP(基本多文种平面):U+0000 - U+FFFF
    • 补充平面:U+10000 - U+10FFFF

编码转换步骤

  1. 确定码点数值:将 U+XXXX 转换为十进制或十六进制整数
  2. 按编码规则分段:根据不同编码方式分割为多个代码单元
  3. 字节序处理:对多字节编码(UTF-16/32)处理字节顺序
  4. 生成字节序列:将代码单元转换为具体字节值

Unicode 的编码方式

在统一码中,汉字“字”对应的数字是23383。在统一码中,我们有很多方式将数字23383表示成程序中的数据,包括:UTF-8、UTF-16、UTF-32。UTF是“UCS Transformation Format”的缩写,可以翻译成统一码字符集转换格式,即怎样将统一码定义的数字转换成程序数据。

Unicode 码点(如 U+6C49 表示“汉”)需要通过编码方案转换为字节序列。常见的编码方式包括:

1、UTF-8

特点:变长编码(1-4 字节);兼容 ASCII(ASCII 字符占 1 字节);适合网络传输和存储(节省空间)

UTF-8编码规则表

码点范围字节数格式(二进制)
U+0000-U+007F10xxxxxxx
U+0080-U+07FF2110xxxxx 10xxxxxx
U+0800-U+FFFF31110xxxx 10xxxxxx 10xxxxxx
U+10000-U+10FFFF411110xxx 10xxxxxx 10xxxxxx 10xxxxxx

注:ASCII 字符(U+0000-U+007F)保持单字节不变!

转换步骤(以 U+6C49 为例)

  1. 十进制值:27721
  2. 二进制:0110 1100 0100 1001
  3. 分段填充:
    1110xxxx 10xxxxxx 10xxxxxx
    ↓ 填充
    11100110 10110001 10001001
  4. 十六进制表示:E6 B1 89

2、UTF-16

特点

变长编码(2 或 4 字节);

基本多语言平面(BMP)字符用 2 字节,辅助平面字符用 4 字节(代理对机制);

广泛用于 Java、Windows 系统。

基本机制

如果码点<0x10000,码点U的UTF-16编码就是U对应的16位无符号整数。

如果码点≥0x10000,我们先计算U'=U-0x10000,然后将U'写成二进制形式:yyyy yyyy yyxx xxxx xxxx,U的UTF-16编码(二进制)就是:110110yyyyyyyyyy 110111xxxxxxxxxx。

  • 基本单位:2字节(16位)
  • 代理对:当码点 > U+FFFF 时使用两个代理单元
    • 高代理(High Surrogate):U+D800 - U+DBFF
    • 低代理(Low Surrogate):U+DC00 - U+DFFF

转换公式(以 U+1F000 为例)

  1. 计算偏移量:U+1F600 - U+10000 = 0xF000
  2. 高代理:0xD800 + (0xF000 >> 10) = D83C
  3. 低代理:0xDC00 + (0xF000 & 0x3FF) = DE00
  4. 最终表示:D83C DE00

字节序标记(BOM)

BOM 字节序列含义
FE FFUTF-16BE(大端)
FF FEUTF-16LE(小端)

3、UTF-32

特点

定长编码(固定 4 字节);

直接存储码点,处理简单但空间效率低;

适用于需要快速随机访问的场景。

直接映射

  • 每个码点直接对应 4 字节(32位)
  • 示例:U+6C49 → 0x00006C49(大端)或 496C0000(小端)
字符:A (U+0041)
内存布局(大端):
00000000 00000041
内存布局(小端):
41000000 00000000

4、BOM(字节顺序标记)

作用:标识文本的字节序(大端序或小端序)和编码类型。

常见 BOM 值:

  • UTF-8: EF BB BF

  • UTF-16 LE: FF FE

  • UTF-16 BE: FE FF

  • UTF-32 LE : FF FE 00 00

  • UTF-32 BE : 00 00 FE FF

编程实现示例

Python:

# UTF-8 编码
text = "😊"
utf8_bytes = text.encode('utf-8')
print(utf8_bytes.hex())  # f09f988a

# UTF-16 编码
utf16_bytes = text.encode('utf-16-be')
print(utf16_bytes.hex())  # d83dde00

# 码点转换
code_point = ord('😊')  # 128522
hex_value = hex(code_point)  # '0x1f60a'

Java:

String text = "😊";
// UTF-8 编码
byte[] utf8 = text.getBytes(StandardCharsets.UTF_8);
// UTF-16 编码
byte[] utf16be = text.getBytes("UTF-16BE");
// 码点操作
int codePoint = text.codePointAt(0);

JavaScript:

const text = '😊';
// 获取码点
const codePoint = text.codePointAt(0); // 128522
// 手动转换函数
function codePointToUTF8(cp) {
  if (cp < 0x80) return [cp];
  // ...
}

PS:unicode里的emoji表情编码可看以下网站              

emoji表情符号

EMOJIALL网站   :Emoji ZWJ 序列

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值